Skip to content

3.2: Error Handling

Sebastian Schendel edited this page Jun 15, 2021 · 5 revisions

AppApi itself returns informative errors for all internal processes, so you should be able to respond to an occurring error the best way possible. Look at the Exceptions.php file for a wide range of Exception-classes that are thrown throughout the code.

The module catches all kinds of occurring exceptions and errors, and instead returns an error message as JSON with correct status code header. Its not limited to the module's code, in your endpoint functions you can throw whatever you want as well!

throw new \Exception('Internal Server Error.', 500);

If you throw this standard PHP-exception, you will get the following output with a 500 Internal Server Error HTTP status header.

{
  "error": "Internal Server Error.",
  "devmessage": {
    "class": "Exception",
    "code": 500,
    "message": "Internal Server Error.",
    "location": "/Users/sebi/Developer/Test/my-website.local/site/modules/AppApi/classes/Router.php",
    "line": 130
  }
}

The part "devmessage" is only visible for superusers. And you can see it in every request if you have wire('config')->debug;enabled.

And I have one last special thing for you that makes the error handling much more flexible. All the internal exceptions extend the following AppApiException class (which you of course can extend for your own exceptions as well).

class AppApiException extends WireException {
  private $additionals = array();

  public function __construct(string $message, int $code = 500, array $additionals = array(), \Exception $previous = null) {
    $this->additionals = array_merge($this->additionals, $additionals);
    parent::__construct($message, $code, $previous);
  }

  public function __toString() {
    return "{$this->message}";
  }

  public function getAdditionals() {
    return $this->additionals;
  }
}

Whats important here is the additionals array, which can hold additional parameters that will appear in the JSON-output as well.

throw new AppApiException('Internal Server Error.', 418, [
  'my_favorite_number' => 42,
  'test' => 'it works!'
]);

Throwing this AppApiException will result in a response like this:

{
  "error": "Internal Server Error.",
  "my_favorite_number": 42,
  "test": "it works!",
  "devmessage": {
    "class": "Exception",
    "code": 418,
    "message": "I'm a teapot",
    "location": "/Users/sebi/Developer/Test/my-website.local/site/modules/AppApi/classes/Router.php",
    "line": 130
  }
}

So use these powers wisely and write clean code!

Error-Hook

It turns out that there are cases where you don't want to blanket "block" all PHP exceptions and warnings and then output them as JSON via the API. Especially with warnings, there may be use-cases where you need to handle them yourself. Therefore, as of v1.1.6, it is possible to override the Router->registerErrorHandlers() function with your own hook.

You have to be careful that no PHP echoes get through to the end! For example, if a PHP warning is printed before the actual JSON output, this will result in non-valid output!


➡️ Continue with 3.3: Example: Listing Users
⬅️ Back to 3.1: Output Formatting