NAME
Mojolicious::Plugin::Fondation::Problem - Unified API (RFC 9457) and HTML error responses for Fondation
VERSION
version 0.01
SYNOPSIS
# In myapp.conf
plugin 'Fondation' => {
dependencies => [
'Fondation::Problem',
],
};
# In a controller
$c->problem(
status => 422,
title => 'Validation failed',
detail => 'Field "name" is too long (60 > 50)',
type => '/problem/validation',
errors => [
{ detail => 'String too long', pointer => '/name' },
],
);
DESCRIPTION
Fondation::Problem provides a unified error response mechanism via the $c->problem() helper.
For API requests (routes with openapi.path in the match stack), it returns an RFC 9457 application/problem+json response.
For browser (HTML) requests, it renders the problem template using the current layout.
In development mode, all fields are returned (type, detail, errors, instance). In production mode, only status and title are sent — no internal information is leaked.
NAME
Mojolicious::Plugin::Fondation::Problem - Unified API (RFC 9457) and HTML error responses for Fondation
VERSION
version 0.01
HELPERS
problem
$c->problem(
status => 422,
title => 'Validation failed',
detail => 'Field "name" is too long',
type => '/problem/validation',
errors => [{ detail => '...', pointer => '/name' }],
instance => '/logs/abc-123',
);
All arguments are optional. Defaults: status = 500, title = 'Internal Server Error'.
In production mode, only status and title are included in the response. detail, type, errors, and instance are suppressed.
TEMPLATES
problem.html.ep
Rendered for HTML error responses. Receives stash values:
problem_status— HTTP status codeproblem_title— Human-readable error titleproblem_detail— Detailed message (only in development mode)
Uses % layout 'main' — if Fondation::Layout::Bootstrap is loaded, its Bootstrap layout applies. Without any layout plugin, Mojo renders the template content directly (no HTML wrapper) — the page remains functional. A future Fondation core release may provide a minimal HTML5 layout as a dedicated plugin loaded after Bootstrap.
RFC 9457 RESPONSE FORMAT
Content-Type: application/problem+json
{
"status": 422,
"title": "Validation failed",
"detail": "Field \"name\" is too long (60 > 50)",
"type": "/problem/validation",
"errors": [
{ "detail": "String too long", "pointer": "/name" }
]
}
MODE-AWARE BEHAVIOR
The plugin distinguishes between development and production modes:
Development → all fields (type, detail, errors, instance)
Production → only status + title
This follows the RFC 9457 principle that title is constant per problem type (always safe to show) while detail and errors may reveal internal structure.
API DETECTION
API requests are detected using three criteria (any one match is sufficient):
- 1.
openapi.pathin the match stack — set by Mojolicious::Plugin::Fondation::OpenAPI - 2. URL path starts with
/api/— custom API routes outside OpenAPI - 3.
Acceptheader containsapplication/jsonbut nottext/html
Requests matching any of these criteria receive an RFC 9457 application/problem+json response. All other requests receive an HTML error page.
DEPENDENCIES
Mojolicious::Plugin::Fondation
SEE ALSO
Mojolicious::Plugin::Fondation, RFC 9457, Mojolicious::Plugin::Fondation::OpenAPI
AUTHOR
Daniel Brosseau <dab@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Daniel Brosseau.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
AUTHOR
Daniel Brosseau <dab@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Daniel Brosseau.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.