Blog
Error Handling in MarkLogic JavaScript APIs
- 3 December, 2024
- By Dave Cassel
The engine that powers MarkLogic's JavaScript includes try/catch
, which is really helpful for capturing errors and handling them gracefully. In a perfect world, your application will recover from the problem and/or provide enough information to a caller to make the problem clear. However, sometimes things happen that we don't anticipate and we need go to the logs. When you do, it's no fun to find a message like this:
2024-11-27 01:56:35.741 Info: Status 500: RESTAPI-SRVEXERR: fn.error(null, 'RESTAPI-SRVEXERR', Sequence.from([statusCode, statusMsg, body])); -- Extension Error: code: 400 message: Bad Request document: Error running JavaScript request
Hmm, what do we do about that? This message comes from a MarkLogic REST API extension and is using the error reporting mechanism that the docs tell us to use. What's missing is the context necessary to figure out what went wrong. Consider this code as part of a REST API extension:
function post(context, params, input) { try { result = someFunctionCall(params.somethingExpected); } catch (error) { returnError(400, 'Bad Request', error.message); } }
Okay good, we're capturing the error and sending a 400 back to the client. Let's also do some logging on error to make it easier to track down the problem. We have a couple options.
xdmp.log
-- Standard logging function, will write out whatever we give it.console.log
-- Very similar toxdmp.log
, but native to JavaScript, not just MarkLogic.console.trace
-- Similar toconsole.log
, but includes a stack trace with the error message.
If our goal is to track down exactly where a problem happened, it looks like the console.trace
function is what we want. But here's the catch: console.trace
tells you where you are when you call that function. If you're in a catch
, that's the stack trace you get. What you want is the stack trace from where the error happened.
Logging the Stack
Here's some code we can drop into Query Console:
function doStuff() { if (1 === 1) { throw new Error('boo'); } } try { doStuff(); } catch (err) { xdmp.log(`xdmp log error message: ${err.stack}`); console.trace(`console trace: ${err.message}`) }
Let's see what we get in the error log.
2024-12-03 20:05:22.423 Info: xdmp log error message: Error: boo 2024-12-03 20:05:22.423 Info:+ at doStuff (<anonymous>:3:11) 2024-12-03 20:05:22.423 Info:+ at <anonymous>:8:3 2024-12-03 20:05:22.423 Info: Trace: console trace: boo 2024-12-03 20:05:22.423 Info:+ at ([anonymous]:11:11)
Notice that our first message from xdmp.log
prints err.stack
, which points us to line 8 (the call to doStuff
) and line 3 (where the exception is thrown). On the other hand, console.trace
points us to line 11, where we call console.trace
in the catch.
Conclusion
Getting the stack trace is very helpful for investigating errors, but we have to make sure we're capturing the right information. Logging err.stack
gives us what we need and can save a lot of time.
Share this post:
4V Services works with development teams to boost their knowledge and capabilities. Contact us today to talk about how we can help you succeed!
The engine that powers MarkLogic's JavaScript includes try/catch, which is really helpful for capturing errors and handling them gracefully. In...