NAME

PAGI::FastAPI::Middleware::ExceptionHandler - Typed Exception-to-Handler Dispatch for PAGI::FastAPI

VERSION

Version v1.2.5

SYNOPSIS

use PAGI::FastAPI::Middleware::ExceptionHandler;

package My::Errors::NotFound;
sub new    ($class, %args) { return bless { %args }, $class }
sub message { return $_[0]->{message} // 'Not Found' }

package main;

my $handler = PAGI::FastAPI::Middleware::ExceptionHandler->new(
    handlers => {
        'My::Errors::NotFound' => async sub ($err, $c) {
            $c->status(404);
            return { detail => $err->message };
        },
    },
    default_handler => async sub ($err, $c) {
        $c->status(500);
        return { detail => 'Internal Server Error' };
    },
);

$app->add_middleware(async sub ($c, $next) {
    return await $handler->handle($c, $next);
});

$app->get('/items/{id}',
    handler => async sub ($c) {
        my $item = My::DB->find($c->path_param('id'))
            or die My::Errors::NotFound->new(message => 'No such item');
        return $item;
    }
);

DESCRIPTION

Wraps the rest of the middleware/handler chain in an eval, and dispatches any thrown exception to a registered handler based on the exception's class (via blessed() and isa()), falling back to a default_handler if given, or re-throwing if nothing matches.

This intentionally mirrors Python FastAPI's @app.exception_handler(SomeError) pattern, adapted to a middleware + registry shape that fits PAGI::FastAPI's existing add_middleware extension point rather than requiring any change to route registration or dispatch internals.

Relationship to core's own error convention: PAGI::FastAPI's built-in dependency mechanism already has its own failure convention, a dependency sets $c->status(>=400) and returns a body hash, which PAGI::FastAPI checks for directly without any exception being thrown at all. This module doesn't replace that; it's for the separate case of actual Perl exceptions (die) escaping a handler or a dependency, which core has no built-in registry for.

METHODS

new(%options)

  • handlers - HashRef mapping exception class name (string) to a coderef of async sub ($exception, $c) { ... }. The empty string key '' catches plain (non-blessed) exceptions, e.g. from die "message".

  • default_handler - (Optional) Coderef of the same shape, used when no registered class matches. If omitted, unmatched exceptions are re-thrown.

handle($c, $next)

Call this from an add_middleware wrapper, exactly as eg/rate_limit_demo.pl does for PAGI::FastAPI::Middleware::RateLimit.

CAVEATS

Handler lookup for subclasses (via isa()) iterates the registered handlers in hash order when there's no exact class match, so if an exception could match more than one registered parent class, which one wins is not guaranteed. Register an exact match for any exception class where this ambiguity matters.

SEE ALSO

PAGI::FastAPI::Middleware::RateLimit, PAGI::FastAPI::Middleware::BotProtection

AUTHOR

Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>

REPOSITORY

https://github.com/manwar/PAGI-FastAPI

BUGS

Please report any bugs or feature requests through the web interface at https://github.com/manwar/PAGI-FastAPI/issues. I will be notified and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc PAGI::FastAPI::Middleware::ExceptionHandler

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright (C) 2026 Mohammad Sajid Anwar.

This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License (2.0).