Part of the issue here is how you’re using wrapAsync. You need to pass the function reference in as an argument. What you’re doing is calling the function and passing the returned value to wrapAsync
Also, from your code, myService doesn’t use a callback, so the code in the callback will never be run, so it will never throw and error; and without a callback, wrapAsync doesn’t do anything
As far as I can see, your sendGridServices.sendEmail function catches your error and returns it, but never re-throws it, while your Meteor method has a try catch for code that doesn’t throw.
As @copleykj says, you are preventing the error from bubbling into the method’s catch handler.
In addition, it’s an async function and you aren’t awaiting it in the method.
I think the first thing to do is revisit how try/catch handlers work, and how promises and async functions work.
Then have a read of how they interact with Meteor’s method system here:
Then you can fix your code by:
not swallowing the error in sendGridServices’s methods
making sure you await the result of promises and async functions
correctly handling errors in the place that you can do something about those errors.
thanks a lot @copleykj and @coagmano for pointing me in the right direction!
I read the article and your comments and made it work (and more importantly got a better understanding of what’s going on )
correctly handling errors in the place that you can do something about those errors.
What do you mean with that? My goal was to reflect the error to the client so the user can contact me in case of an unforseen error with the details.
By that I mean that, generally speaking, errors should be allowed to bubble up the stack until something can be done about it, or you reach a boundary. Which means you should avoid catching and re-throwing.
You’ve got the right idea that in the case the system can’t recover from an error, you should reflect that back to the user, which means the error should be caught in the UI, so that it can be presented to the user and handled by them.
Of course, since web apps are split between client and server, we have a boundary at the API surface - the Meteor method - where the error needs to be caught, transformed and transmitted to the client.
Meteor will do this automatically if an error is thrown in a method, but often isn’t super descriptive (so it doesn’t leak details about system internals by default). So it’s still better to transform it yourself with new Meteor.Error
In your specific case, I mean that you can skip the catches in sendGridServices and catch in the method.
One last thing to keep in mind is that errors only bubble through synchronous code, so just be careful with errors around async calls. Make sure you await if you can, otherwise using .catch( handlers on Promises, or check for error in a callback.