How do you handle errors in Node.js server code?
Currently, I'm working with a large codebase. The codebase is split into different services and each service has its own controller. Now the controller is interacting with the outside world. From this what I have gathered is the error should be handled only in the controller functions.
I am not sure if this is the best approach or not but seems usable.
It is partially correct. Errors should be handled in the controller layer so that you don't send weird content in the API response. This doesn't necessarily mean you shouldn't handle errors in the Service or any other layer.
To put it in other words, by the time the error propogation reaches controller layer, "Ideally", the error should have the message appropriate enough to send it as API response. Now this is possible only if you handle the unknown and rethrow with appropriate message inside the service layer.
Ex: Suppose you've maintained unique email field in User model in Database. When you try to add the user with an existing email, DB returns the error in its own format like
message being Duplicate Key Identified: emailAddress and
errorCode being some number. Based on this, you'd have to catch the error and rethrow new error with appropriate message or error code.
Sometimes, you'd perform the validation upfront, there you'd have to throw the same error.
So the point is; separate the error concerns based on its context. If you handle each and every error inside the controller, you're tightly coupling all the layers with controller. In case, you want to use one service inside the another, you'd end up duplicating the error handling. Plus, unit tests of your service would look ugly containing all the bloatware of excepting weird DB messages instead of simple error codes.