hefestoapicontainer

Control de errores

El flujo de directivas ejecuta las directivas una detrás de otra. Si una directiva lanza una excepción, el flujo normal se interrumpe y solo se ejecutan las directivas en ERROR_FLOW y AFTER_FLOW.

Lanzar una excepción

Para lanzar una excepción desde cualquier directiva:

$state->memory()->set('error.status', 400);
$state->memory()->set('error.message', 'id is mandatory');
throw new \Exception('id is mandatory');

No es obligatorio almacenar error.status y error.message en memory, pero si lo haces, la respuesta HTTP incluirá ese status y ese mensaje.

También puedes usar la directiva ThrowError directamente desde el api.yaml:

ThrowError:
  directive: ThrowError
  status: 404
  message: "Not Found"

OnError (para APIs que devuelven JSON)

La directiva OnError se ejecuta en ERROR_FLOW y formatea el error como JSON. Al crear una API desde el cliente viene configurada por defecto en el after:

after:
  OnError:
    directive: OnError
    groups:
      - ERROR_FLOW

OnError lee error.status y error.message de memory y devuelve:

{
  "error": "id is mandatory"
}

Con el código HTTP correspondiente (400 en este caso).

Crear un manejador de errores personalizado

Si tu API devuelve HTML (vistas), puedes crear tu propia directiva de manejo de errores. Sustituye OnError por tu directiva en el ERROR_FLOW:

after:
  MyCustomError:
    directive: MyErrorHandler
    groups:
      - ERROR_FLOW

Ejemplo de directiva que devuelve una vista de error personalizada:

<?php /*dlv-code-engine***/

$status = $state->memory()->get('error.status') ?? 500;
$message = $state->memory()->get('error.message') ?? 'Error interno';

if ($status == 404) {
    View::run($state, [
        'name' => 'not-found',
        'staticBasePath' => $state->map('main')->get('staticBasePath'),
        'css' => ['general', 'error'],
        'data' => [
            'message' => $message
        ]
    ]);
} else {
    $state->message()->setStatus((int)$status);
    $state->message()->setHeader('content-type', 'application/json');
    $state->message()->setBodyAsArray(['error' => $message]);
}

Esta directiva muestra una vista amigable para errores 404 y devuelve JSON para el resto de errores.