简体   繁体   中英

How to add caller details to error stack trace in node.js?

I have a function called inner that performs a series of asinc operations:

function inner(input) {
    return step1(input)
    .then(step2)
    .then(step3)
    .catch((e) => {
        throw e
    })
}

I rethrow the error from inner so I could handle the error in caller level.

Here is a simple example:

app.get('/', function(req, res){
    inner(req)
    .then(result => {
        res.render('foo', result)
    }).catch((e) => {
        res.render('error', e);

        //eventually this would be changed to logger.error(e)
        console.log(e);
    })
})

The problem is that when I log the error the stack trace shows only the function inner but not the caller file. If I would to use this function twice in my code and error happens then I would need to know which part of my code called it.

How can I add caller information to error stack trace?

Non-standard feature

Since Error.prototype.stack document tags it as a non-standard feature, different platforms may have different behaviours and formats.

For example, I tested it in Chrome with following files:

index.html

<!doctype html>
<html>
  <head>
    <script src="inner.js"></script>
    <script src="caller1.js"></script>
    <script src="caller2.js"></script>
  </head>
  <body></body>
</html>

inner.js

function inner() {
  return new Promise((resolve, reject) => {
    reject(new Error('Oh no'))
  }).catch(e => { throw e })
}

caller1.js and caller2.js

inner().catch(e => { console.log(e.stack) })

And the result in console :

Error: Oh no
    at Promise (setup.js:3)
    at Promise (<anonymous>)
    at inner (setup.js:2)
    at caller1.js:1
Error: Oh no
    at Promise (setup.js:3)
    at Promise (<anonymous>)
    at inner (setup.js:2)
    at caller2.js:1

Both inner() and caller are showed in the stack trace.

Workaround

In your case, you may manually log it in the caller's catch() .

If the code is executed in the browser, use document.currentScript and its src property to get the filename.

Edit: in Node.js

I tested it in Node.js v8.1.2, and the inner() and caller were both displayed as well.

By the way, a paragraph in the document got my attection:

It is important to note that frames are only generated for JavaScript functions. If, for example, execution synchronously passes through a C++ addon function called cheetahify , which itself calls a JavaScript function, the frame representing the cheetahify call will not be present in the stack traces

This may be the reason we get inconsistent results.

In any case, I'm afraid you still have to manually log the filename, which depends on how you import and execute them in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM