Gestione delle eccezioni
Configurazione
config/exception.php
return [
// Qui è possibile configurare la classe di gestione delle eccezioni
'' => support\exception\Handler::class,
];
In modalità multi-applicazione, è possibile configurare una classe di gestione delle eccezioni separata per ogni applicazione, vedere Multi-Applicazione.
Classe di gestione delle eccezioni predefinita
Nel webman, le eccezioni sono gestite di default dalla classe support\exception\Handler
. È possibile modificare la classe predefinita di gestione delle eccezioni modificando il file di configurazione config/exception.php
. La classe di gestione delle eccezioni deve implementare l'interfaccia Webman\Exception\ExceptionHandlerInterface
.
interface ExceptionHandlerInterface
{
/**
* Registra il log
* @param Throwable $e
* @return mixed
*/
public function report(Throwable $e);
/**
* Reinderizza la risposta
* @param Request $request
* @param Throwable $e
* @return Response
*/
public function render(Request $request, Throwable $e) : Response;
}
Reindirizzamento della risposta
Il metodo render
nella classe di gestione delle eccezioni è utilizzato per reindirizzare la risposta.
Se il valore debug
nel file di configurazione config/app.php
è impostato su true
(di seguito indicato come app.debug=true
), verranno restituite informazioni dettagliate sull'eccezione, altrimenti verranno restituite informazioni concise sull'eccezione.
Se la richiesta è in attesa di una risposta in formato json, le informazioni sull'eccezione restituite saranno in formato json, come ad esempio
{
"code": "500",
"msg": "Informazioni sull'eccezione"
}
Se app.debug=true
, i dati json includeranno anche un campo trace
con i dettagli della traccia delle chiamate.
È possibile scrivere una propria classe di gestione delle eccezioni per modificare la logica predefinita di gestione delle eccezioni.
Eccezione Commerciale BusinessException
A volte potremmo voler interrompere una richiesta all'interno di una funzione nidificata e restituire un messaggio di errore al client; in questo caso possiamo utilizzare l'eccezione BusinessException
per farlo.
Ad esempio:
<?php
namespace app\controller;
use support\Request;
use support\exception\BusinessException;
class FooController
{
public function index(Request $request)
{
$this->chackInpout($request->post());
return response('hello index');
}
protected function chackInpout($input)
{
if (!isset($input['token'])) {
throw new BusinessException('Parametro errato', 3000);
}
}
}
Nell'esempio sopra verrà restituito
{"code": 3000, "msg": "Parametro errato"}
Nota
L'eccezione BusinessException non richiede di essere catturata da un blocco try-catch; il framework si occuperà automaticamente di catturare e restituire un output appropriato in base al tipo di richiesta.
Eccezione Commerciale Personalizzata
Se la risposta sopra non soddisfa le tue esigenze e ad esempio vuoi cambiare msg
in message
, è possibile creare una propria eccezione MyBusinessException
.
Creare il file app/exception/MyBusinessException.php
con il seguente contenuto:
<?php
namespace app\exception;
use support\exception\BusinessException;
use Webman\Http\Request;
use Webman\Http\Response;
class MyBusinessException extends BusinessException
{
public function render(Request $request): ?Response
{
// Se la richiesta è in formato json, restituisci i dati in formato json
if ($request->expectsJson()) {
return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
}
// Altrimenti, restituisci una pagina
return new Response(200, [], $this->getMessage());
}
}
In questo modo, quando viene lanciata l'eccezione nella logica di business con
use app\exception\MyBusinessException;
throw new MyBusinessException('Parametro errato', 3000);
una richiesta in formato json riceverà una risposta in json simile a quella seguente
{"code": 3000, "message": "Parametro errato"}
Nota
Poiché l'eccezione BusinessException è relativa ad errori di logica di business (ad esempio errori nei parametri di input dell'utente), è prevedibile; di conseguenza, il framework non la considera un errore fatale e non vi registrerà nessun log.
Conclusione
In qualsiasi situazione in cui si desideri interrompere la richiesta corrente e restituire un messaggio al client, si può considerare l'utilizzo dell'eccezione BusinessException
.