Search code examples
javascriptnode.jspromisees6-promisetext-decoding

Get Out of a TextDecoderStream() from NodeJS


When I send an error message from my express nodejs app using res.status(400).send(err.stack);, I cannot seem to get out of the decoder stream I setup on the receiving end.

Here is my code in the browser (limited to the fetch portion):

fetch("/the/url", {
    method: "POST",
    body: formData,
}).then(response => {
    if (response.status === 200) {
        return response.blob().then((data) => {
            return data;
        });
    } else {
        return new Promise((resolve, reject) => {
            let err_message = "";
            let reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
            reader.read().then(({done, value}) => {
                // When no more data needs to be consumed, close the stream
                if (done) {
                    reject(err_message);
                    return;
                }
                // Enqueue the next data chunk into our target stream
                err_message += value;
            });
        }).then((res) => {
            return (res)
        }).catch((err) => {
            return (err)
        });
    }
}).then((res) => {
    console.log(res)
}).catch((err) => {
    console.log(err)
});

I have put breakpoints on all subsequent then and catch but it never resolves/rejects.

Appreciate any pointers.


Solution

  • In case it's helpful to someone, you need to make a recursive call to the same function to break out properly. As per the following :

    fetch("/the/url", {
        method: "POST",
        body: formData,
    }).then(response => {
        if (response.status === 200) {
            return response.blob().then((data) => {
                return data;
            });
        } else {
            return new Promise((resolve, reject) => {
                let err_message = "";
                let reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
                reader.read().then(function processText({done, value}) {
                    // When no more data needs to be consumed, close the stream
                    if (done) {
                        reject(err_message);
                        return;
                    }
                    // Enqueue the next data chunk into our target stream
                    err_message += value;
                    return reader.read().then(processText);
                });
            }).then((res) => {
                return (res)
            }).catch((err) => {
                return (err)
            });
        }
    }).then((res) => {
        console.log(res)
    }).catch((err) => {
        console.log(err)
    });
    

    from https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/getReader