Master PHP Exception Handling with Tinywan: Install, Configure, and Customize Errors

This guide explains the distinction between exceptions and errors in PHP, shows how to install the Tinywan exception‑handler package, configure it for Webman, use built‑in and custom exception classes, customize JSON responses, and extend the handler for advanced scenarios such as DingTalk notifications.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Master PHP Exception Handling with Tinywan: Install, Configure, and Customize Errors

Understanding Exceptions vs. Errors in PHP

PHP treats all abnormal situations as errors, unlike languages such as Java where exceptions are the sole error‑reporting mechanism. An exception represents a logical or business‑flow error that occurs during runtime, while an error usually stems from syntax or environment problems and cannot be caught with try‑catch.

Installation

composer require tinywan/exception-handler

Configuration

Define the handler class in config/exception.php:

return [
    // Exception handling class
    '' => \Tinywan\ExceptionHandler\Handler::class,
];

For Webman‑admin projects, add the same entry to /plugin/admin/config/exception.php. To catch missing routes, configure /plugin/admin/config/route.php with a fallback that throws \Tinywan\ExceptionHandler\Exception\RouteNotFoundException:

Route::fallback(function () {
    throw new \Tinywan\ExceptionHandler\Exception\RouteNotFoundException();
}, 'admin');

Basic Usage Example

use support\Request;
use support\Response;
use Tinywan\ExceptionHandler\Exception\BadRequestHttpException;

class Token {
    public function issueToken(Request $request): Response {
        $params = $request->post();
        if (empty($params)) {
            throw new BadRequestHttpException('账号或密码不能为空');
        }
    }
}

When the exception is thrown, the handler returns a JSON response such as:

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=utf-8

{
    "code": 0,
    "msg": "账号或密码不能为空",
    "data": {}
}

If debug is true in config/app.php, a detailed stack trace and request information are included; otherwise only the concise message is shown.

Creating a Custom Exception Class

Extend \Tinywan\ExceptionHandler\Exception\BaseException and set the HTTP status code and message:

<?php
declare(strict_types=1);

namespace support\exception;

use Tinywan\ExceptionHandler\Exception\BaseException;

class MethodNotAllowedException extends BaseException {
    public $statusCode = 405;
    public $errorMessage = '请求行中指定的请求方法不能被用于请求相应的资源';
}

Using the Custom Exception

use support\Request;
use support\Response;
use support\exception\MethodNotAllowedException;

class Token {
    public function issueToken(Request $request): Response {
        $params = $request->post();
        if (empty($params)) {
            throw new MethodNotAllowedException();
        }
    }
}

Built‑in Exception Classes

BadRequestHttpException (400)

UnauthorizedHttpException (401)

ForbiddenHttpException (403)

NotFoundHttpException (404)

RouteNotFoundException (404)

TooManyRequestsHttpException (429)

ServerErrorHttpException (500)

Customizing the JSON Response Body

Edit config/plugin/tinywan/exception-handler/app.php to change the status code and the body array. The default body is:

{
  "code": 0,
  "msg": "Too Many Requests",
  "data": null
}

Example of a custom body with HTTP status 200:

{
  "error_code": 200,
  "message": "请求太多请稍后重试"
}

Extending the Handler

When more complex behavior is needed, create a class that extends \Tinywan\ExceptionHandler\Handler and override methods such as solveExtraException, triggerNotifyEvent, or buildResponse:

namespace support;

use Illuminate\Validation\ValidationException;
use Tinywan\ExceptionHandler\Handler;
use Webman\Http\Response;

class ErrorHandler extends Handler {
    protected function solveExtraException(\Throwable $e): void {
        if ($e instanceof ValidationException) {
            $this->errorMessage = $e->validator->errors()->first();
            $this->errorCode = 422;
            return;
        }
        parent::solveExtraException($e);
    }

    protected function triggerNotifyEvent(\Throwable $e): void {
        // custom notification logic (e.g., DingTalk)
        parent::triggerNotifyEvent($e);
    }

    protected function buildResponse(): Response {
        return json([
            'code' => $this->statusCode,
            'msg'  => $this->errorMessage,
            'data' => $this->responseData,
        ]);
    }
}

Exception Notification via DingTalk

DingTalk notification example
DingTalk notification example

Supported Plugin Exception Classes

JwtTokenException (JWT authentication plugin)

ValidateException (Validate validator plugin)

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendException Handlingerror-management
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.