Error Model
Plumego does not impose a single global error-handling mechanism.
This is a deliberate design choice.
Instead of hiding errors behind framework abstractions,
Plumego expects errors to be explicit, local, and intentional.
This document explains the error model Plumego encourages,
and how it fits into the overall request lifecycle.
Errors Are Part of Control Flow
In Plumego, errors are not exceptional events handled magically by the framework.
They are:
- Ordinary values
- Explicitly returned
- Explicitly checked
- Explicitly translated into responses
This aligns with Go’s core philosophy:
Errors are values, not control flow hacks.
Where Errors Can Occur
Errors may occur at multiple stages of a request:
- Before the handler (middleware)
- Inside the handler
- Inside application or domain logic
- During response writing
Plumego does not collapse these into a single mechanism.
Each stage is responsible for handling errors at its own boundary.
Errors in Middleware
Middleware often encounters errors such as:
- Authentication failure
- Authorization denial
- Rate limit exceeded
- Invalid request state
In these cases, middleware should:
- Write an appropriate HTTP response
- Stop the request by not calling
next()
Example (conceptual):
if !authorized {
ctx.JSON(http.StatusUnauthorized, errorResponse("unauthorized"))
return
}
next()
Middleware errors are terminal by design.
Errors in Handlers
Handlers are responsible for translating application errors into HTTP responses.
Typical flow:
- Call application logic
- Receive a value or an error
- Decide how to represent that error to the client
Example:
user, err := service.GetUser(id)
if err != nil {
ctx.JSON(http.StatusNotFound, errorResponse(err))
return
}
ctx.JSON(http.StatusOK, user)
The handler owns:
- HTTP status codes
- Response format
- Error visibility
This keeps error handling explicit and readable.
Errors in Domain and Application Logic
Domain and application code should:
- Return errors as values
- Avoid HTTP-specific concerns
- Avoid framework-specific types
Example:
func (s *UserService) GetUser(id string) (*User, error) {
if id == "" {
return nil, ErrInvalidID
}
// ...
}
The domain layer does not decide how errors are exposed over HTTP.
That decision belongs to the boundary layer (handlers).
Error Propagation Strategy
Plumego encourages a top-down error propagation model:
- Domain returns errors
- Handlers interpret errors
- Middleware handles cross-cutting failures
There is no global error bus or exception handler.
Every error path is visible in code.
Panic vs Error
Plumego makes a clear distinction:
- Errors represent expected failure modes
- Panics represent programmer errors or unrecoverable states
Expected conditions should be expressed as errors, not panics.
Panic Recovery
Panic recovery is typically handled via middleware.
A recovery middleware:
- Uses
defer - Recovers from panic
- Logs the incident
- Writes a safe error response
This ensures:
- The process does not crash
- The request fails gracefully
- The failure is observable
Panics should never be part of normal control flow.
Error Responses Are an Application Concern
Plumego does not enforce:
- A standard error response schema
- A fixed error code system
- Automatic JSON error serialization
This is intentional.
Different systems require different error semantics.
Plumego leaves these decisions to the application.
Avoiding Global Error Handlers
Global error handlers often:
- Hide where errors originate
- Make behavior implicit
- Complicate debugging
Plumego prefers:
- Local handling
- Explicit branching
- Clear ownership of decisions
If an error response is sent, it should be obvious where and why.
Common Anti-Patterns
Treating Errors as Exceptions
Avoid designs where errors “bubble up” invisibly.
If an error matters, handle it explicitly.
Mapping Domain Errors Directly to HTTP Everywhere
Centralize error-to-response mapping where possible,
but keep it explicit and readable.
Using Panic for Business Logic
Panics are not a shortcut for error handling.
If a failure is expected, it should be an error.
Error Model and Testability
Explicit error handling improves testability:
- Handlers can be tested for specific error cases
- Domain logic can be tested without HTTP
- Failure modes are easy to simulate
Hidden error handling makes tests brittle and incomplete.
Summary
Plumego’s error model is:
- Explicit
- Local
- Go-idiomatic
- Boundary-driven
Errors are values that must be handled consciously.
There is no framework magic to save you — and that is the point.
Next
You have completed the Concepts section.
At this point, you should have a complete mental model of how Plumego works.
From here, you can move on to:
→ Architecture (structuring real systems)
→ Guides (solving concrete problems)
→ Patterns (recommended ways of working)
All three build directly on the concepts you now understand.