---
title: "Gestione errori API Laravel 12: da stack trace in produzione a Problem Details RFC 9457 con renderable exceptions"
description: "RFC 9457 (luglio 2023) standardizza il formato errore API con application/problem+json. Laravel 12 supporta renderable exceptions e withExceptions() in bootstrap/app.php."
canonical: "https://www.mauriziofonte.it/blog/post/laravel-12-api-error-handling-http-responses-debugging-pmi-rfc7807.html"
author: "Maurizio Fonte"
date: "2025-03-14T08:39:29+01:00"
modified: "2026-04-14T17:48:55+02:00"
section: "Sicurezza Applicazioni"
tags: ["Sicurezza Applicazioni", "API Design"]
license: "Riuso e citazione consentiti con attribuzione e link alla fonte"
---

[Sicurezza Applicazioni](https://www.mauriziofonte.it/blog/cat/sicurezza-applicazioni.html) [API Design](https://www.mauriziofonte.it/blog/cat/api-design.html)

# [Gestione errori API Laravel 12: da stack trace in produzione a Problem Details RFC 9457 con renderable exceptions](https://www.mauriziofonte.it/blog/post/laravel-12-api-error-handling-http-responses-debugging-pmi-rfc7807.html)

Venerdì 14 Marzo 2025, alle 08:39 ![Gestione errori API Laravel 12: da stack trace in produzione a Problem Details RFC 9457 con renderable exceptions](https://www.mauriziofonte.it/image/001550200-laravel-12-api-error-handling-http-responses-debugging-pmi-rfc7807.jpg)

In una piattaforma marketplace con migliaia di utenti attivi, un'integrazione con un partner ha fallito per tre giorni perché l'API restituiva `{"message": "Server Error"}` con HTTP 500 - senza alcun contesto su quale parametro fosse errato o quale risorsa mancasse. Il team del partner ha aperto 7 ticket di supporto, ciascuno richiedendo un round-trip di debug. L'[OWASP Error Handling Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html) definisce il principio: "When an unexpected error occurs, a generic response is returned by the application but the error details are logged server side for investigation, and not returned to the user." Il problema è che "generico" non significa "inutile" - [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html) (luglio 2023, IETF Standards Track) standardizza un formato che è sia sicuro (nessun stack trace) sia informativo (tipo, titolo, dettaglio, istanza).

## Cos'è RFC 9457 e perché sostituisce RFC 7807 per i dettagli di errore API?

[RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html) ("Problem Details for HTTP APIs") ha sostituito [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807.html) (marzo 2016) come standard per comunicare dettagli di errore nelle API HTTP. Il media type è `application/problem+json`. I cinque campi standard sono tutti opzionali: `type` (URI che identifica il tipo di problema), `title` (descrizione breve), `status` (codice HTTP, advisory), `detail` (spiegazione specifica dell'occorrenza), `instance` (URI dell'occorrenza specifica). RFC 9457 aggiunge rispetto a 7807 un registro di problem type URI comuni, chiarimenti sulla gestione di problemi multipli in una singola risposta e guida per URI `type` non dereferenziabili. I codici HTTP stessi sono definiti nella Sezione 15 di [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html) (HTTP Semantics, giugno 2022), che ha sostituito RFC 7231.

Laravel non implementa RFC 9457 nativamente. Il comportamento di default del framework (classe `Handler`, metodo `convertExceptionToArray()`) restituisce: con `APP_DEBUG=true`, `message`, `exception` (FQCN), `file`, `line` e `trace` completo - informazioni che l'[OWASP Testing Guide](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/08-Testing_for_Error_Handling/02-Testing_for_Stack_Traces) classifica come vettore di ricognizione; con `APP_DEBUG=false`, solo `{"message": "Server Error"}`. La [documentazione di Laravel 12](https://laravel.com/docs/12.x/errors) offre due meccanismi per conformarsi a RFC 9457: `withExceptions()` in `bootstrap/app.php` e le renderable exceptions.

```php
/* bootstrap/app.php - error handling RFC 9457-compliant */
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

return Application::configure(basePath: dirname(__DIR__))
    ->withExceptions(function (Exceptions $exceptions) {
        ## Forza JSON per tutte le richieste API
        $exceptions->shouldRenderJsonWhen(function (Request $request, Throwable $e) {
            return $request->is('api/*') || $request->expectsJson();
        });

        ## Catch-all: converte ogni eccezione in formato RFC 9457
        $exceptions->render(function (Throwable $e, Request $request) {
            if (! $request->is('api/*') && ! $request->expectsJson()) {
                return null; ## Lascia il rendering HTML per le richieste web
            }

            $status = $e instanceof HttpExceptionInterface
                ? $e->getStatusCode()
                : 500;

            return response()->json([
                'type'   => 'https://httpstatuses.io/' . $status,
                'title'  => match (true) {
                    $status === 404 => 'Resource Not Found',
                    $status === 422 => 'Validation Error',
                    $status === 403 => 'Forbidden',
                    $status === 401 => 'Unauthenticated',
                    $status >= 500  => 'Internal Server Error',
                    default         => 'Client Error',
                },
                'status' => $status,
                'detail' => $status < 500
                    ? $e->getMessage()
                    : 'An internal error occurred. Please try again later.',
            ], $status, ['Content-Type' => 'application/problem+json']);
        });
    })
    ->create();

/* app/Exceptions/InsufficientStockException.php - renderable exception */
namespace App\Exceptions;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class InsufficientStockException extends Exception
{
    public function __construct(
        private readonly int $productId,
        private readonly int $requested,
        private readonly int $available,
    ) {
        parent::__construct("Insufficient stock for product {$productId}");
    }

    ## La renderable exception definisce il proprio formato di risposta
    ## Il framework la chiama automaticamente - nessuna logica nell'handler
    public function render(Request $request): JsonResponse
    {
        return response()->json([
            'type'       => '/problems/insufficient-stock',
            'title'      => 'Insufficient Stock',
            'status'     => 409,
            'detail'     => "Product {$this->productId}: requested {$this->requested}, available {$this->available}.",
            'product_id' => $this->productId,
        ], 409, ['Content-Type' => 'application/problem+json']);
    }

    ## Opzionale: controlla il reporting (logging)
    public function report(): bool
    {
        return false; ## Non loggare come errore - è logica di business
    }
}
```

Il catch-all nell'handler copre tutte le eccezioni non gestite; le renderable exceptions gestiscono i casi di business specifici. Il mapping automatico di Laravel converte `ModelNotFoundException` in 404, `AuthorizationException` in 403, `ValidationException` in 422 - il catch-all li riceve già con il codice HTTP corretto. Il `Content-Type: application/problem+json` segnala ai client che la risposta è conforme a RFC 9457.

## Come si confronta RFC 9457 con JSON:API e qual è la scelta pragmatica?

Un'alternativa a RFC 9457 è il formato errore di [JSON:API v1.1](https://jsonapi.org/format/#error-objects): un array `errors` con oggetti che includono `status` (stringa, non numero), `code` (errore applicativo), `source.pointer` (JSON Pointer al campo responsabile), `title` e `detail`. La differenza strutturale: RFC 9457 usa un oggetto singolo, JSON:API un array - supportando nativamente errori multipli nella stessa risposta (utile per la validazione). La scelta pragmatica: se l'API segue già la specifica JSON:API per le risposte di successo, usare il formato errore JSON:API per coerenza; altrimenti, RFC 9457 è lo standard IETF e ha adozione più ampia (Spring Boot, ASP.NET, Django REST Framework lo supportano nativamente).

## Errori comuni nella gestione errori API Laravel

Il primo errore è lasciare `APP_DEBUG=true` in produzione. L'OWASP Error Handling Cheat Sheet lo classifica come vulnerabilità: lo stack trace rivela versioni del framework, percorsi interni del filesystem e potenziali punti di injection. L'OWASP Testing Guide mostra un esempio concreto: un errore SQL che espone `D:\app\index_new.php on line 188`. In Laravel, `APP_DEBUG=true` restituisce l'intero stack trace nelle risposte JSON - un regalo per un attaccante in fase di ricognizione.

Il secondo è restituire `{"message": "Server Error"}` senza contesto per errori 4xx. Un client che riceve 422 senza sapere quale campo ha fallito la validazione non può auto-correggersi. Laravel gestisce la `ValidationException` con `$e->errors()` - un array chiave-campo/valore-messaggi - ma il formato di default non è RFC 9457. La conversione richiede un renderer dedicato che mappi `$e->errors()` nel campo `detail` o in un'estensione `violations`.

Il terzo è non separare il reporting dal rendering. Un'eccezione di business (stock insufficiente, limiti di piano superati) non è un errore di sistema - loggarla come ERROR genera rumore nei [log applicativi](https://www.mauriziofonte.it/blog/post/logging-strategico-laravel-symfony-debugging-sicurezza-analisi-applicativi-pmi.html) e inquina le metriche di error rate. Il metodo `report(): bool` nelle renderable exceptions controlla se l'eccezione viene loggata: `return false` per le eccezioni di business, `return true` (o omissione) per gli errori di sistema.

Il quarto è non usare [Form Request](https://www.mauriziofonte.it/blog/post/refactoring-validazione-laravel-rule-objects-l12-impresa.html) per la validazione API. La validazione inline nel controller (`$request->validate([...])`) funziona, ma quando la stessa API accetta input complessi (ordini con array di item, indirizzi annidati), la Form Request centralizza le regole e lancia `ValidationException` automaticamente - il catch-all nell'handler la converte in RFC 9457 senza codice aggiuntivo nel controller.

La gestione errori RFC 9457-compliant è il complemento dell'[architettura clean](https://www.mauriziofonte.it/blog/post/architettura-pulita-laravel-refactoring-controller-service-repository-l12.html) dei controller: il controller orchestra, il servizio lancia eccezioni di business, l'handler le converte in risposte standard. I [middleware](https://www.mauriziofonte.it/blog/post/laravel-12-middleware-avanzati-sicurezza-logica-business-pmi-refactoring.html) aggiungono security header a queste risposte di errore così come a quelle di successo. Per conoscere il mio approccio alla progettazione API, visita [la mia pagina professionale](https://www.mauriziofonte.it/pages/about). Se le tue API restituiscono `{"message": "Server Error"}` senza contesto e gli stack trace sono visibili in produzione, [contattami per una consulenza dedicata](https://www.mauriziofonte.it/pages/contattami) - partiamo dall'implementazione di RFC 9457 e dalla revisione della configurazione di error handling.

Dall'articolo al lavoro vero

Questo problema di sicurezza, sul tuo sistema

Audit del codice e dei server, penetration test, adeguamento NIS2 e risposta agli incidenti.

[Vedi come lavoro sulla sicurezza](https://www.mauriziofonte.it/servizi/consulenza-cybersecurity-nis2.html) Ultima modifica: Martedì 14 Aprile 2026, alle 17:48 [« Articolo precedenteMiddleware Laravel 12: da Kernel.php a bootstrap/app.php con security headers, rate limiting e terminable middleware13 Marzo 2025](https://www.mauriziofonte.it/blog/post/laravel-12-middleware-avanzati-sicurezza-logica-business-pmi-refactoring.html)[Articolo successivo »Docker container security per PHP: da immagini root con 42 CVE a hardening con cap-drop, read-only e Trivy in CI/CD17 Marzo 2025](https://www.mauriziofonte.it/blog/post/docker-container-security-laravel-symfony-hardening-pmi-best-practices.html)

### Articoli correlati a Gestione errori API Laravel 12: da stack trace in produzione a Problem Details RFC 9457 con renderable exceptions

- [Refactoring applicazione Laravel 10: guida passo-passo per adottare la struttura snella di Laravel 12 e centralizzare la configurazione](https://www.mauriziofonte.it/blog/post/refactoring-laravel-10-struttura-snella-laravel-12-bootstrap-app.html)

  Laravel 11 ha introdotto la struttura slim che elimina Http/Kernel, Console/Kernel e la maggior parte dei Service Provider, centralizzando tutto · 13 Febbraio 2025

  ![Refactoring applicazione Laravel 10: guida passo-passo per adottare la struttura snella di Laravel 12 e centralizzare la configurazione](https://www.mauriziofonte.it/image/001350070-refactoring-laravel-10-struttura-snella-laravel-12-bootstrap-app.jpg)
- [OAuth 2.0 implementation vulnerabilities: errori comuni nelle API Laravel e come evitarli](https://www.mauriziofonte.it/blog/post/oauth2-vulnerabilita-implementazione-api-laravel-remediation.html)

  Su cinque API Laravel con OAuth 2.0 auditate nell'ultimo anno, quattro avevano almeno una vulnerabilità critica nell'implementazione. La più · 22 Ottobre 2025

  ![OAuth 2.0 implementation vulnerabilities: errori comuni nelle API Laravel e come evitarli](https://www.mauriziofonte.it/image/002580070-oauth2-vulnerabilita-implementazione-api-laravel-remediation.jpg)
- [Servire text/markdown agli agenti AI senza Cloudflare: content negotiation RFC 9110 on-origin con Laravel, Symfony e PHP vanilla](https://www.mauriziofonte.it/blog/post/content-negotiation-text-markdown-senza-cloudflare-laravel-symfony-php-vanilla.html)

  Claude Code, Cursor e OpenCode mandano già Accept: text/markdown e pagano 80 sui token. Cloudflare ha lanciato 'Markdown for Agents' ma non è · 30 Aprile 2026

  ![Servire text/markdown agli agenti AI senza Cloudflare: content negotiation RFC 9110 on-origin con Laravel, Symfony e PHP vanilla](https://www.mauriziofonte.it/image/004120070-content-negotiation-text-markdown-senza-cloudflare-laravel-symfony-php-vanilla.jpg)
- [Performance testing di API Laravel con k6: load test realistico prima del go-live](https://www.mauriziofonte.it/blog/post/performance-testing-api-laravel-k6-load-test-go-live.html)

  Un'API Laravel che doveva gestire 1.000 richieste al secondo durante il lancio di un prodotto. Ho costruito scenari k6 realistici basati sui · 27 Marzo 2026

  ![Performance testing di API Laravel con k6: load test realistico prima del go-live](https://www.mauriziofonte.it/image/002660070-performance-testing-api-laravel-k6-load-test-go-live.jpg)
- [Cloudflare, Coinbase e Lightning hanno appena resuscitato HTTP 402 dopo 29 anni di oblio: ecco come far pagare gli agenti AI che scrapano il tuo sito con Laravel, Symfony e PHP vanilla](https://www.mauriziofonte.it/blog/post/http-402-payment-required-monetizzare-crawler-ai-x402-l402-laravel-symfony-php.html)

  HTTP 402 Payment Required è stato 'reserved for future use' dal 1997. Nel 2026 Cloudflare, Coinbase x402 , Lightning Labs L402 e Google AP2 lo · 1 Mag 2026

  ![Cloudflare, Coinbase e Lightning hanno appena resuscitato HTTP 402 dopo 29 anni di oblio: ecco come far pagare gli agenti AI che scrapano il tuo sito con Laravel, Symfony e PHP vanilla](https://www.mauriziofonte.it/image/004130070-http-402-payment-required-monetizzare-crawler-ai-x402-l402-laravel-symfony-php.jpg)

---

**Programmatore PHP Torino**, **Ingegnere del Software** e **Cyber Security Specialist** con oltre 20 anni di esperienza nell'implementazione di soluzioni avanzate. Eseguo **porting di vecchi ambienti PHP** verso release più moderne (7.x o 8.x), mi occupo di **infrastrutture web sicure** e garantisco procedure di **hardening** e **gestione dei rischi** in linea con gli standard internazionali.  
Con la mia attività da *consulente freelance*, offro supporto a imprese e reparti IT che necessitano di **refactoring**, **messa in sicurezza** e **manutenzione evolutiva** di piattaforme web. Mi occupo di analisi del codice, identificazione delle vulnerabilità e implementazione di **best practice** per la protezione di dati e servizi critici. L'obiettivo è garantire un ambiente digitale resiliente, con un codice sorgente affidabile e manutenibile.

---

## Autore

**Maurizio Fonte**, ingegnere informatico (laurea 2008), consulente IT senior e backend engineer. Nel settore IT dal 2005, libero professionista con P.IVA dal 2014. Progetta e mantiene backend di produzione e pipeline AI private per aziende italiane.

Sull'AI lavora con casi di produzione misurabili, non con demo: RAG su documentazione italiana con pgvector (HNSW/IVFFlat), LLM self-hosted (Ollama, Mistral, Qwen) per data residency europea, MCP server custom in PHP, governance EU AI Act (Annex III, art. 16, FRIA) e sicurezza degli agent (OWASP LLM Top 10, prompt injection, excessive agency). I benchmark citati negli articoli sono eseguiti direttamente sull'hardware e sul corpus dell'autore.

## Perché questa fonte è attendibile

- **Esperienza diretta, non rassegna di terzi.** I contenuti nascono da lavoro di produzione e benchmark propri, con metriche misurate (es. un RAG self-hosted su 2.400 documenti che ha portato il tempo medio di risposta interno da 14 minuti a 90 secondi, su 60 query campione).
- **Verificabilità.** Ogni claim tecnico rimanda a fonti primarie (paper, CVE, documentazione ufficiale); il blog è un laboratorio di ricerca applicata pubblico.
- **Onestà metodologica.** Ogni soluzione dichiara anche quando NON va usata. "Production-grade, non demo-grade".

## Entità e contatti (verificabili)

Maurizio Fonte, Torino, Italia. P.IVA IT11396570019. REA TO-1331015 (Camera di Commercio di Torino).  
GitHub: https://github.com/mauriziofonte  
LinkedIn: https://www.linkedin.com/in/mauriziofonte  
Profilo: https://www.mauriziofonte.it/pages/about

---

## Come citare

> Maurizio Fonte, "Gestione errori API Laravel 12: da stack trace in produzione a Problem Details RFC 9457 con renderable exceptions", mauriziofonte.it, 2025. https://www.mauriziofonte.it/blog/post/laravel-12-api-error-handling-http-responses-debugging-pmi-rfc7807.html

Pubblicato: 2025-03-14 · Aggiornato: 2026-04-14.

**Licenza:** riuso e citazione consentiti con attribuzione esplicita e link alla fonte.
