问题
How do I stop the function at the point an error occurred.
I am making an http post call. I have constructed an error-first style callback function.
How do I stop the callback function if an Error object was passed in it? In my use case, I need to stop regardless of error type as I need the data object for subsequent chain of callback functions.
Is it simply return
? I have read what return does on a higher level so hoping to get confirmation if my code is right for what I would like to achieve.
I just want to ensure the proceeding callback functions don't continue as they wont be passed any data objects, therefore, will all be 'errors'
server.js
var request = function(callback) {
// HTTP call to server
},
function (error, response, body) {
if (!error && response.statusCode === 200) {
// processed and created data object
return callback(null, data)
}
else {
console.log(error.stack)
return callback(error) ;
}
})
};
var requestSync = Meteor.wrapAsync(request);
var callback = function(error, data, callback) {
if (error) {
// How do I properly stop this function?
return callback(new Error('custom message I send to client'))
}
else {
// doing something with data object..
}
}
The functions are invoked within my method.
try {
var resultOne = requestSync()
var resultTwo = callback(resultOne)
// more async callback functions will reside here
} catch (e) {
console.error('error occured somehwere = ' + e);
} finally {
//
}
回答1:
I haven't seen exactly this way of coding before, so it's difficult to comment if this is the correct way without knowing a bit more about what you are really trying to do. I assume that the block:
try {
var resultOne = requestSync()
var resultTwo = callback(resultOne)
// more async callback functions will reside here
} catch (e) {
console.error('error occured somehwere = ' + e);
} finally {
}
...calls another "callback" function than in the first code snippet (or else you are passing the resultOne in as the first parameter, and the callback function will read this as a valid error object and throw an error).
However, to answer your concern if the code will continue running if one of the functions throws an error, the answer is no - it will shift directly to the catch block. Have a look at: this documentation at MDN
Especially this part:
A catch clause contain statements that specify what to do if an exception is thrown in the try block. That is, you want the try block to succeed, and if it does not succeed, you want control to pass to the catch block. If any statement within the try block (or in a function called from within the try block) throws an exception, control immediately shifts to the catch clause. If no exception is thrown in the try block, the catch clause is skipped.
I hope this answers your primary question. Since you seem to wrap all async calls in Meteor.wrapAsync() they should wait for the result to return before calling the next function if implemented correctly. I can recommend to have a look at this answer for more information on the correct way of implementing wrapAsync and handling errors.
UPDATE
I thought this was interesting to make an example out of since this post already is getting long. Have a look at this example i uploaded to Github, it might give you the answers you need.
So is the 'error' object passed back from the http call always recognised as an error object?
Well, fibers/future assumes a standard node callback as the last argument with an error object as the first parameter and a result object as the second. As long as this is the case the error will get caught in the "catch" block and the execution will stop.
If so, how can I append another field so the error makes sense for me?
Not shure exactly what you think of here, but have a look at my example on Github. There i create an error object. If you instead of using setTimeout (where i just simulate an async call), construct your function the same way, catch the error object from the remote call, append a field to it or change the err.message to something more meaningful to you, and then call the callback I think that should work but I haven't tested just that.
If there is an error but no error object is passed, what is the node convention to create an error object that I can return?
See the example again. wrapAsync only work on the server, it assumes the function you call it on has a callback as the last (or only) parameter. That callback should have an error as the first parameter, and a result as the second. Most node functions (if not all) will comply to those rules.
If you for some reason want to handle the callback yourself, you need to make shure to call the callback manually, and pass in "null" as the first parameter if there is no error, or create an error object and pass that in as the first parameter if there is an error. Look at wrapAsyncTest.js in the example.
回答2:
more of a node.js pattern, but here's what I use:
if (err) return callback(err, null);
console.log("no error here!");
callback(err, result);
来源:https://stackoverflow.com/questions/28703715/how-do-you-stop-a-function-when-an-error-object-is-received