dontReport = config('core.exception.app.handler.dont_report', []); parent::report($exception); } public function render(Request $request, Throwable $exception): Response { // Apidoc异常处理响应 // if ($exception instanceof \hg\apidoc\exception\HttpException) { // return response(json_encode([ // "code" => $exception->getCode(), // "message" => $exception->getMessage(), // ], JSON_UNESCAPED_UNICODE), $exception->getStatusCode()); // } // 处理Laravel验证异常 if ($exception instanceof ValidationException) { $errors = $exception->errors(); return json([ 'code' => 422, 'message' => 'Validation failed', 'data' => $errors, ], 422); } $this->initializeConfig(); $this->addRequestInfoToResponse($request); $this->processException($exception); $this->addDebugInfoToResponse($exception); $this->triggerEvents($exception); return $this->buildResponse(); } protected function initializeConfig(): void { $this->config = array_merge($this->config, config('core.exception.app.handler', [])); } protected function addRequestInfoToResponse(Request $request): void { $this->responseData = array_merge($this->responseData, [ 'domain' => $request->host(), 'method' => $request->method(), 'request_url' => $request->method() . ' ' . $request->uri(), 'timestamp' => date('Y-m-d H:i:s'), 'client_ip' => $request->getRealIp(), 'request_param' => $request->all(), ]); } protected function processException(Throwable $e): void { if ($e instanceof BaseException) { $this->handleBaseException($e); } else { $this->handleOtherExceptions($e); } } protected function handleBaseException(BaseException $e): void { $this->statusCode = $e->statusCode; $this->header = $e->header; $this->errorCode = $e->errorCode; $this->errorMessage = $e->errorMessage; $this->error = $e->error; if (isset($e->data)) { $this->responseData = array_merge($this->responseData, $e->data); } } protected function handleOtherExceptions(Throwable $e): void { $status = $this->config['status']; $this->errorMessage = $e->getMessage(); switch (true) { case $e instanceof BadRouteException: $this->statusCode = $status['route'] ?? 404; break; case $e instanceof ValidateException: $this->statusCode = $status['validate'] ?? 400; break; case $e instanceof JwtTokenInBlacklistException: case $e instanceof JwtTokenInvalidException: $this->statusCode = $status['jwt_token'] ?? 401; break; case $e instanceof JwtTokenExpiredException: $this->statusCode = $status['jwt_token_expired'] ?? 401; break; case $e instanceof JwtRefreshTokenExpiredException: $this->statusCode = $status['jwt_refresh_token_expired'] ?? 401; break; case $e instanceof \InvalidArgumentException: $this->statusCode = $status['invalid_argument'] ?? 415; $this->errorMessage = '预期参数配置异常:' . $e->getMessage(); break; case $e instanceof ServerErrorHttpException: $this->statusCode = 500; $this->errorCode=-1; break; default: $this->statusCode = $status['server_error'] ?? 500; $this->errorMessage = 'Internal Server Error'; $this->error = $e->getMessage(); break; } } protected function addDebugInfoToResponse(Throwable $e): void { if (config('app.debug', false)) { $this->responseData['error_message'] = $e->getMessage(); $this->responseData['error_trace'] = explode("\n", $e->getTraceAsString()); $this->responseData['file'] = $e->getFile(); $this->responseData['line'] = $e->getLine(); } } protected function triggerEvents(Throwable $e): void { $this->triggerNotifyEvent($e); $this->triggerTraceEvent($e); } protected function triggerNotifyEvent(Throwable $e): void { } protected function triggerTraceEvent(Throwable $e): void { } protected function buildResponse(): Response { $bodyKey = array_keys($this->config['body']); $bodyValue = array_values($this->config['body']); // 当HTTP状态码为错误状态时,确保code不为0 $code = $this->errorCode ?: ($bodyValue[0] ?? 0); if (($this->statusCode >= 400 || $this->statusCode < 100) && $code === 0) { $code = -1; } $responseBody = [ $bodyKey[0] ?? 'code' => $code, $bodyKey[1] ?? 'msg' => $this->errorMessage, $bodyKey[2] ?? 'data' => $this->responseData, ]; $header = array_merge(['Content-Type' => 'application/json;charset=utf-8'], $this->header); return new Response($this->statusCode, $header, json_encode($responseBody)); } }