Docs Error Model

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:

  1. Before the handler (middleware)
  2. Inside the handler
  3. Inside application or domain logic
  4. 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:

  1. Write an appropriate HTTP response
  2. 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:

  1. Call application logic
  2. Receive a value or an error
  3. 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.