What are the latest best practices for catching exceptions in the following?
In a Template helper
In a global helper
In an event handler
in a Meteor.call
in a Meteor.method
in a publish
in a subscribe
Also, are the best practices around handling the exception once you’ve caught it?
For example, just logging to the console inside of Chrome on a production box is probably not best way to capture exceptions (but is the default).
Should we use something like the toastr package to alert the user something went wrong, write to the console, and then log to a collection or to the file system?
I’ve come to realize the right way may be whatever works for you. You can always build upon and improve later but if it works then why not make that YOUR right way. Regardless, I’d be interested in an article about your method too!
Should I wrap the Meteor method in a try/catch – then inside the catch throw a Meteor.Error? Then on the Meteor call, instead of waiting for the callback to log the error, should I wrap the call in a try/catch and log in the catch?
rough example:
/client/meteor_call.js
try {
Meteor.call('do_something', message); <- async call, will catch get called?
} catch (e) {
console.log(e);
}
/lib/meteor_methods.js
do_something: function (message) {
var return_id = '';
try {
return_id = collection_name.insert(message);
} catch (e) {
throw new Meteor.Error(500, 'exception in do_something', e);
} finally {
return return_id;
}
}
Above, the Meteor.Error thrown in the Meteor method would bubble up to the Meteor call on the client, and since the client is not handling the error in the callback, won’t the catch on the client catch the it?
If I need to do something with in the callback of the Meteor call, then I can do this I guess:
/client/meteor_call.js
try {
Meteor.call('do_something', message, function (err, return_value) {
// do stuff with return_value
}
} catch (e) {
console.log(e);
}
But should I place another try/catch within the callback, or just leave it out and catch in the outer try/catch?
I agree! I’ve asked several questions about best practices myself. I’ve also spent many hours thinking I was not doing things right when in fact it was just fine, just offering my thoughts mate nothing more. As far as your exception work, I really am interested in how you’re going about this. I’ve had issues trapping errors properly.
I thought that meteor.calls last parameter was a callback function… this is what I have been doing.
Meteor.call('User.invite', profile._id, function (err, userId) {
if (!err) {
var user = Meteor.users.findOne(userId)
sAlert.info("Successfully invited " + user.profile.name + "!");
} else {
sAlert.error("Failed to invite user")
}
});
Then I made a subscribeWithOnError for subscription errors.
subscribeWithOnError = function () {
check(arguments[0], String);
var subName = arguments[0];
var subParams = [].slice.call(arguments, 1, arguments.length);
var params = [subName].concat(subParams);
params.push({
onError: function (e) {
if (e.error === 401) {
if (Meteor.user ()) {
sAlert.error("You are not permitted to view this page");
Router.current().next();
} else {
sAlert.warning("You must be logged in to view this page");
Router.go('Auth.login');
}
// ... etc
} else {
Router.current().render('error', {
data: {
message: "Unknown Error",
error: e
}
});
}
}
});
Meteor.subscribe.apply(Meteor, params);
}
Out of curiosity, why don’t you want a callback for your methods on the client? Meteor calls are always asynchronous on the client side. There are no fibers on the client to help.
On the client, if you do not pass a callback and you are not inside a stub, call will return undefined, and you will have no way to get the return value of the method. That is because the client doesn’t have fibers, so there is not actually any way it can block on the remote execution of a method.
But my general rule is, if I don’t need to display something to the user or perform a sequential action (with or without an return value) after the Meteor.call – why have a callback?
Otherwise, I just want a Meteor.call(‘do_something’, message).
But even if I do have a callback, why handle every exception in each callback if I have several that run in a row (async or not)?
My point is, I don’t want to handle exceptions in the callback. I want to handle only functionality that needs to happens in sequence in the callback – nothing more.
From the docs:
Also, ‘unblock: when called, allows the next method from this client to begin running.’ What does this mean to you @khamoud ?
Meteor.call('some_call', some_param, function (err, return_value) {
// inside here, on the client, i'm happy to be sequential!
Meteor.call('another_thing_in_seq', return_value, function (err, return_value) {
// do someting seq
}
});
If you don’t care about the order of which the methods are completing (not returning) then you can call them like that. The problem is that they won’t return anything. You won’t have access to the errors or the return so doing a try/catch block on Meteor.call() won’t help. The only way to catch an error is inside the callback.