Search code examples
javascriptnode.jstypescriptexpresserror-handling

Where to throw Errors on MVC Model: Service or Controller?


I'm creating an Backend with Express using the MVC Model, but I still don't know where to throw the errors.

I'm using the express-async-errors and the http-errors , so I can throw the Error anywhere, that the Error will be handled by a middleware that I've created.

But my question is:

1 - I throw the complete Error on my Service like this:

export default class UserService {

  public error(){
    throw createError(404,"Error Message")
  }
}

and don't create try/catch blocks on my Controller

2 - I throw a simple Error or message on my Service and let the Controller deal with it:

Service

export default class UserService {

  public error(){
    throw Error("Error Message")
  }
}

Controller

export default class UserController {
 public simpleMethod(){
  try {
    userService.error()
  } catch (error:any) {
    throw createError(404,error.message)
  }

 }
}

3 - Or just return a value like and object with an property called error and let the Controller handle everything, like this:

Service

export default class UserService {

  public error(){
    return {error:"Error Message"}
  }
}

Controller

export default class UserController {
  public simpleMethod() {
    const message = userService.error()

    if (message.error) {
      throw createError(404, message.error)
    }
  }
}

Note: I was thinking the best way to handle this was directly on the Service, because you can be more specific on the type of error, but some people recommend to do this on Controller, so, what is the correct way to handle this?


Solution

  • Where the error is throwed depends if it is a full HTTP APP or not.

    1 - Full HTTP API/Server

    If it is a API used only for HTTP Requests, you should throw the Errors on the Service Layer, just like the first example on my question, because:

    • You can throw more specific status and messages

    • Your Controller gets cleaner

    • The Controller don't need to always have a try/catch block to treat the Error

    • The Service errors are handled the same way all over your application

    • Let the Controller layer just handle the requisition/response, because that's what it's made for!

    2 - Not a Full HTTP API/Server

    If it is not only used for HTTP Requests, the best way is to throw the Error on the Service Layer only with the specific Error Code and message, and let the Controller handle the Error passed to it, and decided what status to give it and how to send it.

    In this case it's the best option, because the Service can be used on other places of your App, not only the HTTP Controllers