Fabiomad85

Fabiomad85

Member Since 7 years ago

Experience Points
0
follower
Lessons Completed
1
follow
Lessons Completed
1
stars
Best Reply Awards
4
repos

3 contributions in the last year

Pinned
⚡ SPID authentication proxy based on Shibboleth service provider
⚡ Code repository for Node Cookbook Third Edition, published by Packt
⚡ A modern, ES6-friendly Lambda Authorizer ready for integration with Serverless Framework and Auth0.
⚡ Command line utility to launch Express local API for claudia-api-builder. Test drive your lambda functions before deployment (https://www.npmjs.com/package/claudia-local-api)
Activity
Oct
15
1 day ago
Activity icon
fork

Fabiomad85 forked suddi/claudia-local-api

⚡ Command line utility to launch Express local API for claudia-api-builder. Test drive your lambda functions before deployment (https://www.npmjs.com/package/claudia-local-api)
Fabiomad85 MIT License Updated
fork time in 19 hours ago
Oct
14
2 days ago
Activity icon
issue

Fabiomad85 issue comment expressjs/express

Fabiomad85
Fabiomad85

Debugging ERR_HTTP_HEADERS_SENT errors in res.render

I work on a large Express app with a lot of async code. Occasionally due to a bug we are calling res.render twice, the second of which causes a ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client error which crashes the app 🤯

I think that due to the nature of render using an async callback, the stack trace is meaningless in terms of identifying where this errant render call was made. E.g.

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:467:11)
    at ServerResponse.header (/usr/src/app/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/usr/src/app/node_modules/express/lib/response.js:170:12)
    at done (/usr/src/app/node_modules/express/lib/response.js:1008:10)
    at render_file (/usr/src/app/node_modules/hbs/lib/hbs.js:49:14)
    at ReadFileContext.callback (/usr/src/app/node_modules/hbs/lib/hbs.js:168:16)
    at FSReqCallback.readFileAfterOpen [as oncomplete] (fs.js:232:13)

🤷‍♂️

I have managed to debug it by monkey-patching res.render and res.send:

app.use((req, res, next) => {
    const render = res.render;
    const send = res.send;
    res.render = function renderWrapper(...args) {
        Error.captureStackTrace(this);
        return render.apply(this, args);
    };
    res.send = function sendWrapper(...args) {
        try {
            send.apply(this, args);
        } catch (err) {
            console.error(`Error in res.send | ${err.code} | ${err.message} | ${res.stack}`);
        }
    };
    next();
});

Which prevents the crash and changes the logs to:

Error in res.send | ERR_HTTP_HEADERS_SENT | Cannot set headers after they are sent to the client | Error
     at ServerResponse.renderWrapper [as render] (/usr/src/app/app/server.js:289:15)
     at index (/usr/src/app/app/controllers/home-controller.js:88:21)
     at processTicksAndRejections (internal/process/task_queues.js:89:5)

The second last line is the exact place the second render call occurred 🎉

Question is, is this a terrible approach? Is there a better way? Or is there potential to make this kind of debugging easier in Express?

Fabiomad85
Fabiomad85

How can I debug this ERR_HTTP_HEADERS_SENT problem?

Sep
14
1 month ago
Activity icon
fork

Fabiomad85 forked codingly-io/serverless-auth0-authorizer

⚡ A modern, ES6-friendly Lambda Authorizer ready for integration with Serverless Framework and Auth0.
Fabiomad85 Updated
fork time in 1 month ago