{"id":19833031,"url":"https://github.com/tinywan/think-exception","last_synced_at":"2026-01-11T08:48:09.486Z","repository":{"id":59051386,"uuid":"535160365","full_name":"Tinywan/think-exception","owner":"Tinywan","description":"exception handler library for ThinkPHP6.0 plugin library","archived":false,"fork":false,"pushed_at":"2024-06-17T02:01:06.000Z","size":100,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-27T01:41:17.784Z","etag":null,"topics":["composer","composer-library","exception-handling","exceptions","php","thinkphp6"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tinywan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-09-11T01:22:33.000Z","updated_at":"2024-07-01T03:07:19.000Z","dependencies_parsed_at":"2024-04-07T10:33:11.960Z","dependency_job_id":"1b3b6710-518a-4319-90eb-63861e114135","html_url":"https://github.com/Tinywan/think-exception","commit_stats":{"total_commits":43,"total_committers":1,"mean_commits":43.0,"dds":0.0,"last_synced_commit":"6afdc8b41c182f2d25dc02328f8771bfc39a8d05"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tinywan%2Fthink-exception","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tinywan%2Fthink-exception/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tinywan%2Fthink-exception/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tinywan%2Fthink-exception/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tinywan","download_url":"https://codeload.github.com/Tinywan/think-exception/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224269191,"owners_count":17283630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["composer","composer-library","exception-handling","exceptions","php","thinkphp6"],"created_at":"2024-11-12T11:39:17.651Z","updated_at":"2026-01-11T08:48:09.448Z","avatar_url":"https://github.com/Tinywan.png","language":"PHP","readme":"# ThinkPHP6.0 exception 异常插件\n\n[![Total Downloads](http://poser.pugx.org/tinywan/think-exception/downloads)](https://packagist.org/packages/tinywan/think-exception)\n[![Daily Downloads](http://poser.pugx.org/tinywan/think-exception/d/daily)](https://packagist.org/packages/tinywan/think-exception)\n[![License](http://poser.pugx.org/tinywan/think-exception/license)](https://packagist.org/packages/tinywan/think-exception)\n[![PHP Version Require](http://poser.pugx.org/tinywan/think-exception/require/php)](https://packagist.org/packages/tinywan/think-exception)\n[![exception-handler](https://img.shields.io/github/last-commit/tinywan/think-exception/main)]()\n[![exception-handler](https://img.shields.io/github/v/tag/tinywan/think-exception?color=ff69b4)]()\n\n## 安装\n\n```phpregexp\ncomposer require tinywan/think-exception\n```\n\n## 配置\n\n### 发布配置\n\n```phpregexp\nphp think tinywan:exception\n```\n这将自动生成 `config/exception.php` 配置文件。\n\n### 配置异常类\n\n日志服务 `app/provider.php`\n\n```php\nreturn [\n    'think\\exception\\Handle' =\u003e tinywan\\Handler::class,\n];\n```\n\n日志订阅 `app/event.php`\n\n```php\nreturn [\n    // 添加一个订阅类\n    'subscribe' =\u003e [\n        \\tinywan\\subscribe\\ExceptionSubscribe::class,\n    ],\n];\n```\n\n## 基本用法\n\n请求参数错误\n```php\nuse tinywan\\exception\\BadRequestHttpException;\n\nclass Token {\n    public function issueToken(Request $request): Response\n    {\n        $params = $request-\u003epost();\n        if (empty($params)) {\n            throw new BadRequestHttpException('账号或密码不能为空');\n        }\n    }\n}\n```\n以上异常抛出错误信息，如下格式：\n```json\nHTTP/1.1 400 Bad Request\nContent-Type: application/json;charset=utf-8\n\n{\n    \"code\": 0,\n    \"msg\": \"账号或密码不能为空\",\n    \"data\": {},\n}\n```\n\u003e 所有返回的异常信息将以json格式返回，以上为`返回简略的异常信息`\n\n所有的异常错误处理器根据配置文件 `config/app.php`中`debug`的值来调整错误显示， 当`debug`值为`true` (表示在调试模式)， 错误处理器会显示异常以及详细的函数调用栈和源代码行数来帮助调试，将返回详细的异常信息。 当`debug`值为`false`，只有错误信息会被显示以防止应用的敏感信息泄漏，将返回简略的异常信息。\n\n返回详细的异常信息\n```json\nHTTP/1.1 400 Bad Request\nContent-Type: application/json;charset=utf-8\n        \n{\n    \"code\": 0,\n    \"msg\": \"password不允许为空\",\n    \"data\": {\n        \"request_url\": \"POST //127.0.0.1:8888/oauth/issue-token\",\n        \"timestamp\": \"2022-03-06 15:19:12\",\n        \"client_ip\": \"172.18.0.1\",\n        \"request_param\": {\n            \"username\": \"webman\"\n        },\n        \"error_message\": \"password不允许为空\",\n        \"error_trace\": \"#0 /var/www/tinywan-admin/app/functions.php(68): Tinywan\\\\Validate\\\\Validate-\u003echeck(Array)\\n#1 /var/www/webman-admin/app/controller/Authentication.php(25): validate(Array, 'app\\\\\\\\common\\\\\\\\vali...')\\n#2 /var/www/webman-admin/vendor/workerman/webman-framework/src/App.php(234): app\\\\controller\\\\Authentication-\u003eissueToken(Object(support\\\\Request))\\n#3 /var/www/webman-admin/app/middleware/AccessControlMiddleware.php(26): Webman\\\\App::Webman\\\\{closure}(Object(support\\\\Request))\\n#4 /var/www/webman-admin/vendor/workerman/webman-framework/src/App.php(228): app\\\\middleware\\\\AccessControlMiddleware-\u003eprocess(Object(support\\\\Request), Object(Closure))\\n#5 /var/www/webman-admin/vendor/workerman/webman-framework/src/App.php(137): Webman\\\\App::Webman\\\\{closure}(Object(support\\\\Request))\\n#6 /var/www/webman-admin/vendor/workerman/workerman/Connection/TcpConnection.php(638): Webman\\\\App-\u003eonMessage(Object(Workerman\\\\Connection\\\\TcpConnection), Object(support\\\\Request))\\n#7 /var/www/webman-admin/vendor/workerman/workerman/Events/Select.php(295): Workerman\\\\Connection\\\\TcpConnection-\u003ebaseRead(Resource id #254)\\n#8 /var/www/webman-admin/vendor/workerman/workerman/Worker.php(2417): Workerman\\\\Events\\\\Select-\u003eloop()\\n#9 /var/www/webman-admin/vendor/workerman/workerman/Worker.php(1541): Workerman\\\\Worker-\u003erun()\\n#10 /var/www/webman-admin/vendor/workerman/workerman/Worker.php(1383): Workerman\\\\Worker::forkOneWorkerForLinux(Object(Workerman\\\\Worker))\\n#11 /var/www/webman-admin/vendor/workerman/workerman/Worker.php(1357): Workerman\\\\Worker::forkWorkersForLinux()\\n#12 /var/www/webman-admin/vendor/workerman/workerman/Worker.php(549): Workerman\\\\Worker::forkWorkers()\\n#13 /var/www/webman-admin/start.php(87): Workerman\\\\Worker::runAll()\\n#14 {main}\"\n    }\n}\n```\n\n## 自定义异常 Response\n\n只支持修改`body`的三个字段的key值。必须保持顺序是：\n- ① 状态码\n- ② 错误消息\n- ③ 响应数据\n\n\u003e 使用场景\n- 每个项目有标准的统一输出，自定义返回内容\n- 前后端分离：前端要求返回的 `HTTP状态码`并不是 `429`，而是 `200` 或者其他\n- 响应的`body`不是 `{\"code\":0,\"msg\":\"Too Many Requests\"}`，而是 `{\"error_code\":200,\"message\":\"Too Many Requests\"}` 等其他内容\n\n### 自定义HTTP状态码\n\n编辑 `config/exception.php` 文件的 `status` HTTP 状态码\n\n### 自定义`body`返回内容\n\n编辑 `config/exception.php` 文件的 `body` 的字段\n\n**默认选项是**\n\n```json\n{\n\t\"code\": 0,\n\t\"msg\": \"Too Many Requests\",\n\t\"data\": null\n}\n```\n**自定义选项参考一**\n\n1、假设`status` HTTP 状态码设置为 `200`\n\n2、假设`body`的数组设为为\n\n```php\n'body' =\u003e [\n\t'error_code' =\u003e 200,\n\t'message' =\u003e '请求太多请稍后重试'\n]\n```\n\n则响应内容为\n```json\nHTTP/1.1 200 OK\nContent-Type: application/json;charset=UTF-8\n\n{\n\t\"error_code\": 200,\n\t\"message\": \"请求太多请稍后重试\"\n}\n```\n其他的可以根据自身业务自定义即可\n\n## 扩展自己的 Handler\n\n当项目需要自定义情况比较多的时候，很可能需要扩展 Handler，此时可以继承 `tinywan\\Handler` 然后修改对应方法即可。\n\n\u003e 使用场景\n- response需要响应`xml`，而不是json格式，只需要覆盖`buildResponse`方法\n- 扩展其他Exception的响应，我只要覆盖`solveExtraException`\n- 要异常推送微信消息，我可以覆盖`triggerNotifyEvent`\n\n自定义异常 `ErrorHandler`\n\n```php\n\nnamespace app\\common;\n\nuse Throwable;\nuse tinywan\\Handler;\n\nclass ErrorHandler extends Handler\n{\n    /**\n     * @desc: 重写处理扩展的异常，增加自己的异常\n     * @param Throwable $e\n     * @author Tinywan(ShaoBo Wan)\n     */\n    protected function solveExtraException(Throwable $e): void\n    {\n        // 用户中心异常处理\n        if ($e instanceof \\ErrorException) {\n            $this-\u003eerrorMessage = '用户中心异常：'.$e-\u003egetMessage();\n            $this-\u003eerrorCode = 400;\n            return;\n        }\n        parent::solveExtraException($e);\n    }\n}\n```\n\n## 异常通知（钉钉机器人）\n\n![dingtalk.png](dingtalk.png)\n\n自定义异常消息\n\n```php\n\n$message = ' - 自定义错误1： 浏览器版本xxx'. \" \\n\";\n$message .= ' - 自定义错误2： 浏览器版本xxx'. \" \\n\";\n\\tinywan\\event\\NotifyEvent::dingTalkRobot([], [], '正式', $message);\n```\n\n## Other\n\n### phpstan\n\n```phpregexp\nvendor/bin/phpstan analyse src\n```\n\n### vendor/bin/php-cs-fixer fix src\n\n```phpregexp\nvendor/bin/php-cs-fixer fix src\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinywan%2Fthink-exception","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinywan%2Fthink-exception","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinywan%2Fthink-exception/lists"}