Home > Software design >  Cannot set headers after they are sent to the client bug with Express and node-postgres
Cannot set headers after they are sent to the client bug with Express and node-postgres

Time:08-11

I'm stuck with the issue of sending response back to the caller after retrieving something from Postgres database.

It appears that headers are automatically written after fetchUserDB is executed (regardless of its success).

This leads to the error ERR_HTTP_HEADERS_SENT when I try to return the response back using res.json() menthod.

These are the headers after fetchUsedDB is called (just before return statement). Checking res._headers you can see that finished is set to true after the call is made.

access-control-allow-origin:    '*'
content-length:    155
content-security-policy:    'default-src 'none''
content-type:    'text/html; charset=utf-8'
x-content-type-options:    'nosniff'
x-powered-by:    'Express'

This is the route managing the endpoint in question:

user.get("/detail",async (req,res)=>{
    const {uid} = req.authToken

    fetchUserDB(uid).then(data=>{
        return res.status(200).json({
            data:data[0],
        })
    }).catch(err=>{
        switch (err.name) {
            case 'NoUserWithUid':
                break;
            default:
                break;
        }
        return res.status(404).json({
            error:"user not found"
        })
    })
})

The error I'm getting is:

Uncaught Error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Here is the fetchUserDB code:

export const fetchUserDB = async (uid)=>{
    client.connect()
    try {
        const query = `SELECT * FROM api.users WHERE firebase_uid = '${uid}'`
        const res = await client.query(query)

        if (res.rows.length == 0) {
            throw new NoUserWithUid(uid)
        }
        return res.rows
    } catch(err){
        console.log(err);
        debugger
    }finally {
        client.end()
    }
}

I'm using Express and node-postgres.

CodePudding user response:

So after 2 days of struggling I found the solution. In one of my Express API middleware I did use next(). What solved the issue was to change it to return next()

This caused completely unexpected behaviour with axios and async/await.

When to use next() and return next() in Node.js

CodePudding user response:

why don't you simplify your code as bellow

user.get("/detail", async (req, res) => {
const {
    uid
} = req.authToken

try {
    const user = await fetchUserDB(uid)
    return res.status(200).json({
        data: data[0],
    })
} catch (err) {
    switch (err.name) {
        case 'NoUserWithUid':
            break;
        default:
            break;
    }
    return res.status(404).json({
        error: "user not found"
    })
}

})

  • Related