Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

213
Views
Exception thrown in nested async / await functions causes unexpected behavior

I have an async function:

const jwtDecode = async (token) => {
    //return jsonwebtoken.verify(token, TOKEN_SECRET)
    console.log("jwt decode, token: " + token)

    try {
        const { payload } = await jose.jwtVerify(token, new TextEncoder().encode(TOKEN_SECRET))

        return payload
    }
    catch (e) {
        console.log("Caught error jwt decode")
        console.error(e.message, e.stack)
        return {}
    }
}

That function is wrapped by a few other async functions, where await is used.

const foo = async (token) => {
    const {userId} = await jwtDecode(token)

    return userId
}

const foo2 = async (token) => {
    const userId = await foo(token)

    return userId
}

const userId = await foo2(token)

When an exception is thrown in jwtDecode, then the whole chain seems to forget about await and executes as if it didn't exist. On top of that, the call to foo2 returns a Promise instead of 'undefined'

I know there is a logical explanation to this. Could someone explain and provide the solution? Thanks

UPDATE:

Here is the full code:

This first call happens in my _middleware.js (I am using Next.js)

export async function middleware(req, ev) {
    ...
    ...
    ...

    const userId = await serverUtils.authorizeRequest(req)

    ...
    ...
    ...
const authorizeRequest = async (req) => {
    const accessToken = req.cookies.PictosAT

    let { userId } = await jwtDecode(accessToken)

    if (!userId) {
        userId = null
    }
    console.log("Authorize request userId is " + userId)
    return userId
}

const jwtDecode = async (token) => {

    console.log("jwt decode, token: " + token)


    try {
        const { payload } = await jose.jwtVerify(token, new TextEncoder().encode(TOKEN_SECRET))

        return payload
    }
    catch (e) {
        console.log("Caught error jwt decode")
        console.error(e.message, e.stack)
        return {}
    }
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You're not catching at the proper place. You need the consumers of jwtDecode to be able to determine if the function succeeded or not. With your current approach, return {} means that at the top of the chain, const userId = await foo2(token) will assign undefined to userId. If you catch inside jwtDecode, that means that its consumers can't see that there was an error.

Figure out where the error can be meaningfully caught. If you want this line:

const userId = await foo2(token)

to not run at all if there's a problem, then either omit the catch entirely so the error is caught even higher up the chain, or re-throw the error inside jwtDecode so other functions can see that it failed.

Another option is to catch at the point of assignment to userId, then check if it's truthy or not.

const jwtDecode = async (token) => {
    const { payload } = await jose.jwtVerify(token, new TextEncoder().encode(TOKEN_SECRET))
    return payload
}
const foo = async (token) => {
    const {userId} = await jwtDecode(token)
    return userId
}

const foo2 = async (token) => {
    return foo(token);
}

// resolve to undefined if there was an error:
const userId = await foo2(token).catch(() => {});
if (!userId) {
  // put your desired error handling here...
  return;
}
// continue on with code that depends on the populated userId here
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!