Error Handling

Echo advocates for centralized HTTP error handling by returning error from middleware
and handlers. Centralized error handler allows us to log errors to external services
from a unified location and send a customized HTTP response to the client.

You can return a standard error or echo.*HTTPError.

For example, when basic auth middleware finds invalid credentials it returns
401 - Unauthorized error, aborting the current HTTP request.

  1. e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
  2. return func(c echo.Context) error {
  3. // Extract the credentials from HTTP request header and perform a security
  4. // check
  5. // For invalid credentials
  6. return echo.NewHTTPError(http.StatusUnauthorized, "Please provide valid credentials")
  7. // For valid credentials call next
  8. // return next(c)
  9. }
  10. })

You can also use echo.NewHTTPError() without a message, in that case status text is used
as an error message. For example, “Unauthorized”.

Default HTTP Error Handler

Echo provides a default HTTP error handler which sends error in a JSON format.

  1. {
  2. "message": "error connecting to redis"
  3. }

For a standard error, response is sent as 500 - Internal Server Error; however,
if you are running in a debug mode, the original error message is sent. If error
is *HTTPError, response is sent with the provided status code and message.
If logging is on, the error message is also logged.

Custom HTTP Error Handler

Custom HTTP error handler can be set via e.HTTPErrorHandler

For most cases default error HTTP handler should be sufficient; however, a custom HTTP
error handler can come handy if you want to capture different type of errors and
take action accordingly e.g. send notification email or log error to a centralized
system. You can also send customized response to the client e.g. error page or
just a JSON response.

Error Pages

The following custom HTTP error handler shows how to display error pages for different
type of errors and logs the error. The name of the error page should be like <CODE>.html e.g. 500.html. You can look into this project for pre-built error pages.

  1. func customHTTPErrorHandler(err error, c echo.Context) {
  2. code := http.StatusInternalServerError
  3. if he, ok := err.(*echo.HTTPError); ok {
  4. code = he.Code
  5. }
  6. errorPage := fmt.Sprintf("%d.html", code)
  7. if err := c.File(errorPage); err != nil {
  8. c.Logger().Error(err)
  9. }
  10. c.Logger().Error(err)
  11. }
  12. e.HTTPErrorHandler = customHTTPErrorHandler

Instead of writing logs to the logger, you can also write them to an external service like Elasticsearch or Splunk.