Reputation: 10858
I'm writing a module that talks to a REST API, and since the REST API provides nice, semantic error responses (e.g. 403 vs. 503), I want to convey those semantic errors to callers.
(Edit: what I mean by that is, the caller should be able to programmatically understand the cause of the error and act accordingly, e.g. display the appropriate UI.)
What's the best way for me to do so?
Create my own Error
subclasses for those semantics, e.g. mymodule.ForbiddenError
, mymodule.ServiceUnavailableError
? Callers would then check instanceof
to derive semantics. This is most typical in statically-typed languages like C# and Java.
Add e.g. a mymoduleCode
property to standard Error
instances, with semantic strings like 'Forbidden'
or 'ServiceUnavailable'
. Node.js itself does this, e.g. code: 'ECONNREFUSED'
.
Some other way?
==
I'm writing another module now, that wraps the first module. I don't want to expose the internal module's errors directly, but it'd be nice to compose/wrap them, for debuggability.
What's again the best way for me to do so?
Add e.g. an internalError
property to my Error
instances that references the internal module's Error
instance. Again C# and Java do this. (Exception#InnerException / Throwable#cause)
Some other way?
Most tooling I've seen, though, only displays the stack
property of Error
instances, so this data would get lost in those cases. Is there a typical/conventional way that already exists?
Upvotes: 6
Views: 2317
Reputation: 10858
Found this great article that talks about this:
http://www.joyent.com/developers/node/design/errors
Too much to paste here, but under "Specific recommendations", items 2 through 5 address this:
- Be clear about what your function does.
- Use
Error
objects (or subclasses) for all errors, and implement theError
contract.- Use the Error's
name
property to distinguish errors programmatically.- Augment the
Error
object with properties that explain details- If you pass a lower-level error to your caller, consider wrapping it instead.
And in particular, the article links to this module for wrapping/composing errors:
https://github.com/joyent/node-verror
I'm not sure I'll necessary follow these exact conventions — e.g. I see value in having an application-domain code
property — but the principles are very helpful.
Upvotes: 5
Reputation: 18427
I'll simply attach an httpCode
property to the error object. KISS
Upvotes: 0
Reputation: 166
The use case you describe is one that is definitely underserved by Node right now. Inasmuch as there are conventions in use, they tend to be some mixture of:
instanceof
to discriminiate between types of errors, but that doesn't feel very JavaScripty.The real problem here is that these are all ad hoc mechanisms and I wouldn't say that any of them have reached critical mass. I think this is in part due to the fact that the combination of asynchronicity and JavaScript makes it tough to correctly and completely handle errors, so the recommendation is generally to shut down the whole process after capturing information about the error.
This doesn't do a great job of dealing with expected errors, but I think most of those errors are either captured by the framework (e.g. Express error handlers) or put into the Node callback convention. In short, I think there's room here to define some conventions, because the state of the art isn't that artful.
Upvotes: 6
Reputation: 15729
I'm pretty new to node as well, so take this with a grain of salt, but I'd go with your #2 option, adding a property. (This is also suggested here).
This is pretty much your original #2 option. If the error handlers just log the stack, not the error itself, that's their fault. :-) (seriously, not sure how you can do any better)
Upvotes: 1
Reputation: 75
Edit I'm new to StackOverflow and Node.js. Someone else should answer this question! :-)
If you're coming from Java/C# welcome to JavaScript! I've never seen a Node.js library use instanceof
to check for error types but as you've stated is pretty common in static languages.
With that said, it's typical to just create new errors, and callback with those using NodeJS's style of callbacks (err, response)
.
I run into error messages from other modules all the time, and it's helpful to know where they came from vs. creating wrapped error messages that may hide where it actually died on me (requiring more on my part to dig around).
An example of creating a function that could handle rest error messages that are strings (or in your case, invalid response):
function myFunction(callback) {
callRestAPI('http://someApi.com/request', function(errorString, jsonResponse) {
if (errorString) {
callback(new Error("something wrong in myFunction! " + errorString));
} else {
callback(null, JSON.parse(jsonResponse));
}
});
}
In your case the "errorString" check would basically be the response (403 / 503) and you can structure your error message to be sent into new Error( ... )
, e.g. new Error('Failed! Got response 403!')
I may have missed your point, maybe someone else can be more thorough.
After a re-read, can you post what module you are wrapping. Is it node-request?
Upvotes: 1