Error Handling
Sometimes you can’t answer a request. The record isn’t there, the visitor
isn’t signed in, the input makes no sense. HTTP has a status code for each of
those, and it matters which one you send — a 404 and a 500 mean quite
different things to a browser, a crawler, a cache and your own monitoring.
The good news is that you don’t have to build those responses yourself. Your
handler just returns an error, and the framework turns it into the right
status in the right format — an HTML error page for a browser, JSON for an API
client — in one place, the same way every time. That is why your handlers
return error.
Typed HTTP errors
These are error values standing for a status code. Return one and the framework knows what to send:
app.ErrUnauthorized // 401
app.ErrForbidden // 403
app.ErrNotFound // 404
app.ErrBadRequest // 400
app.ErrMethodNotAllowed // 405
app.ErrPageExpired // 419
app.ErrUnprocessableEntity // 422
app.ErrInternalServerError // 500Return them from handlers manually:
func MyHandler(c app.Context) error {
return app.ErrNotFound
}Context Error Helpers
The context provides convenience methods for common error responses:
func MyHandler(c app.Context) error {
return c.NotFound()
return c.Unauthorized()
return c.Forbidden()
return c.BadRequest(err)
return c.InternalServerError(err)
return c.ValidationError(err)
return c.PageExpired()
return c.MethodNotAllowed()
return c.UnprocessableEntity(err)
}These methods automatically negotiate JSON vs HTML responses based on the request’s Accept header.
Error Map
The ErrMap lets you map error types to custom handler functions:
// bootstrap/errmap.go
func LoadErrMap() app.ErrMap {
return app.ErrMap{
app.ErrNotFound: func(c app.Context) error {
if c.WantsJSON() {
return c.JSON(app.M{"error": "not found"})
}
return c.Render(res.NewTemplate(c, "404.page.gohtml"))
},
app.ErrUnauthorized: func(c app.Context) error {
return c.Redirect("/login")
},
app.ErrInternalServerError: func(c app.Context) error {
return c.Render(res.NewTemplate(c, "500.page.gohtml"))
},
}
}The generated project includes default error pages for common status codes in templates/:
401.page.gohtml403.page.gohtml404.page.gohtml419.page.gohtml500.page.gohtml
Custom Error Types
Implement the HttpError interface for custom typed errors:
type ValidationFailed struct {
Field string
Message string
}
func (e *ValidationFailed) GetHttpMessage() app.HttpMessage {
return app.HttpMessage{
Status: http.StatusUnprocessableEntity,
Message: e.Field + ": " + e.Message,
}
}App-Level Error Handling
The framework’s recovery middleware catches panics and returns appropriate responses:
middleware.Recovery() // Production: log + 500
middleware.RecoveryWithOpts(middleware.DevelopmentRecoveryOpts) // Dev: log + stack trace