'Error [ERR_STREAM_WRITE_AFTER_END]: write after end

Code explanation: I am returning specific HTML file when user visit specific url:

const http = require('http');
const fs = require('fs');

fs.readFile('./funkcionalnosti-streznika.html', function(err1, html1) {
    fs.readFile('./posebnosti.html', function(err2, html2) {
        if (err1 || err2) {
            throw new Error();
        }

        http.createServer(function(req, res) {
            if (req.url == '/funkcionalnosti-streznika') {
                res.write(html1);
                res.end();
            }
            if (req.url == '/posebnosti') {
                res.write(html2)
                res.end();
            } else {
                res.write('random');
                res.end();
            }
        }).listen(8080)
    })
});

on terminal I've got this error when I visit localhost:8080/funkcionalnosti-streznika:

events.js:288
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at write_ (_http_outgoing.js:637:17)
    at ServerResponse.write (_http_outgoing.js:629:15)
    at Server.<anonymous> (/*filelocation*/:19:21)
    at Server.emit (events.js:311:20)
    at parserOnIncoming (_http_server.js:784:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
Emitted 'error' event on ServerResponse instance at:
    at writeAfterEndNT (_http_outgoing.js:692:7)
    at processTicksAndRejections (internal/process/task_queues.js:85:21) {
  code: 'ERR_STREAM_WRITE_AFTER_END'

I think there is I problem when I close the response too early. How should I change this to be async?.



Solution 1:[1]

You have already realized what the problem is. Let's take a look at this code:

    http.createServer(function(req, res) {
        if (req.url == '/funkcionalnosti-streznika') {
            res.write(html1);
            res.end();
        }
        if (req.url == '/posebnosti') {
            res.write(html2)
            res.end();
        } else {
            res.write('random');
            res.end();
        }
    }).listen(8080)

Let's suppose that req.url is '/funkcionalnosti-streznika'. What happens? It enters the first if, writes html1 and ends res. Then it is checked against '/posebnosti', but it's different, because the first if was true. This means that the else branch will be executed, so res.write('random'); is called, but res was already closed in the first if. Suggestion:

http.createServer(function(req, res) {
    if (req.url == '/funkcionalnosti-streznika') {
        res.write(html1);
        res.end();
    }
    else if (req.url == '/posebnosti') {
        res.write(html2)
        res.end();
    } else {
        res.write('random');
        res.end();
    }
}).listen(8080)

Solution 2:[2]

Just write return after every if, this will stop further execution of the code.

Solution 3:[3]

You can check using inside your API using if (res.writableEnded) return; to see if your middleware have already wrote to the response stream (it used to be response.finished but got deprecated)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Lajos Arpad
Solution 2 harshit bhalla
Solution 3 Korayem