<?php
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
if (request()->expectsJson()) {
$exceptions->render(function (Exception $e) {
$msg = $e->getMessage().' '.$e->getFile().' '.$e->getLine();
$state = -2;
$code = 500;
switch (true) {
case $e instanceof ValidationException:
$msg = $e->getMessage();
$code = 400;
break;
case $e instanceof AuthenticationException:
$msg = 'Not authenticated (login required)';
$state = $code = 401;
break;
case $e instanceof ModelNotFoundException:
case $e instanceof NotFoundHttpException:
$msg = '404(NOT FOUND)';
$state = $code = 404;
break;
case $e instanceof MethodNotAllowedHttpException:
$msg = '405(Method Not Allowed)';
$state = $code = 405;
break;
case $e instanceof UnauthorizedHttpException:
$msg = 'Verification failed';
$state = $code = 422;
break;
case $e instanceof HttpException:
$msg = $e->getMessage();
switch ($e->getStatusCode()) {
case 401:
$state = $code = 401;
break;
default:
$code = $e->getStatusCode();
break;
}
}
return responseHelper(false, $msg, $state, $code);
});
}
})->create();
通过
make:exception
命令创建自定义异常$ php artisan make:exception InvalidRequestException
定义
render
方法<?php namespace App\Exceptions; use Exception; use Illuminate\Http\Request; class InvalidRequestException extends Exception { // 自定义错误码 protected $errorCode; public function __construct(string $message = "", int $errorCode = 0, int $code = 400) { $this->errorCode = $errorCode; parent::__construct($message, $code); } public function render(Request $request) { $data = ['message' => $this->message, 'error_code' => $this->errorCode]; // 返回 json 格式信息 if ($request->expectsJson()) { return response()->json($data, $this->code); } // 返回错误页面 return view('pages.error', $data); } }
自带 ajax 请求识别呢
添加一个请求头就行了
var xhr = new XMLHttpRequest();
xhr.open("GET", "ta", true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// 请求成功
var response = JSON.parse(xhr.responseText);
console.log(response);
}
};
xhr.send();
我是在 app/Exceptions/Handler.php
里面定义, $request->wantsJson()
用来获取是否要返回 JSON
格式数据。
<?php
namespace App\Exceptions;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* The list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
// 数据不存在异常
$this->renderable(function (ModelNotFoundException $e, ?Request $request = null) {
if ($request && $request->wantsJson()) {
$message = __(
'messages.model_not_found',
[
'model' => __('messages.model.'.$e->getModel()),
]
);
return response()->json([
'code' => $e->getCode(),
'message' => $message,
'model' => $e->getModel(),
'ids' => $e->getIds(),
], 404);
}
return response()->view('errors.404', [], 404);
});
// ...
封装个异常处理类,这样就不用频繁修改app.php了,例如
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
(new \App\Exceptions\Handler($exceptions))->handle();
})->create();
然后在Hanler类里面处理,可以参考下:
<?php
namespace App\Exceptions;
use App\Helpers\ApiHelper;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Traits\ForwardsCalls;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Throwable;
class Handler
{
use ForwardsCalls;
protected $dontReport = [
XXXX::class,
];
public function __construct(public Exceptions $exceptions) {}
public function handle() {
// 不需要报告的异常
$this->dontReport($this->dontReport);
// 异常附带context
$this->context(fn (Throwable $e, array $context) => $this->withContext($e, $context));
// 是否需要响应Json
$this->shouldRenderJsonWhen(fn(Request $request, Throwable $e) => $this->shouldReturnJson($request, $e));
// 处理异常响应
$this->respond(function(Response $response, Throwable $e, Request $request) {
if ( !$this->shouldReturnJson($request, $e) ) {
return $response;
}
$data = ['xxxxxx'];
$apiResponse = match(true) {
$e instanceof AuthenticationException => ApiHelper::failed(message: $e->getMessage(), code: 401, extends: $data),
$e instanceof HttpExceptionInterface => ApiHelper::failed(message: $e->getMessage(), code: $e->getStatusCode(), extends: $data),
$e instanceof ValidationException => ApiHelper::validation(messages: $e->errors(), message: $e->getMessage(), extends: $data),
// APP定义异常
$e instanceof AppException => ApiHelper::failed($e->getMessage(), code: $e->getCode(), extends: $data),
default => ApiHelper::error(message: 'Server Error', e: $e, code: 500),
};
return $apiResponse;
});
}
protected function shouldReturnJson(Request $request, Throwable $e)
{
if ($request->is('api/*')) {
return true;
}
return $request->expectsJson();
}
/**
* 附带日志信息
* @param Throwable $e 异常
* @param array $context 异常附带的信息
* @return [type] [description]
*/
protected function withContext(Throwable $e, array $context): array
{
$request = app('request');
try {
return !App::runningInConsole() || isset($_SERVER['LARAVEL_OCTANE']) ? [
'userId' => Auth::check() ? Auth::id() : null,
'ip' => $request->ip(),
'requestId' => $request->attributes->get('request_id'),
'requestUrl' => $request->fullUrl(),
'requestMethod' => $request->method(),
] : [];
} catch (\Throwable $e) {
return [];
}
}
public function __call(string $method, array $parameters)
{
return $this->forwardCallTo($this->exceptions, $method, $parameters);
}
}
我这安装11报错了,是要更新compsoer的源么
composer create-project laravel/laravel:^11.0 lara11
Creating a "laravel/laravel:^11.0" project at "./lara11" Installing laravel/laravel (v11.0.3)
Installing laravel/laravel (v11.0.3): Extracting archive Created project in /var/www/laravels/lara11
@php -r "file_exists('.env') || copy('.env.example', '.env');" Loading composer repositories with package information Updating dependencies Your requirements could not be resolved to an installable set of packages.
Problem 1
- laravel/framework[v11.0.0, ..., v11.0.8] require fruitcake/php-cors ^1.3 -> found fruitcake/php-cors[dev-feat-setOptions, dev-master, dev-main, dev-test-8.2, v0.1.0, v0.1.1, v0.1.2, v1.0-alpha1, ..., 1.2.x-dev (alias of dev-master)] but it does not match the constraint.
- Root composer.json requires laravel/framework ^11.0 -> satisfiable by laravel/framework[v11.0.0, ..., v11.0.8].
<?php
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
if (request()->expectsJson()) {
$exceptions->render(function (Exception $e) {
$msg = $e->getMessage().' '.$e->getFile().' '.$e->getLine();
$state = -2;
$code = 500;
switch (true) {
case $e instanceof ValidationException:
$msg = $e->getMessage();
$code = 400;
break;
case $e instanceof AuthenticationException:
$msg = 'Not authenticated (login required)';
$state = $code = 401;
break;
case $e instanceof ModelNotFoundException:
case $e instanceof NotFoundHttpException:
$msg = '404(NOT FOUND)';
$state = $code = 404;
break;
case $e instanceof MethodNotAllowedHttpException:
$msg = '405(Method Not Allowed)';
$state = $code = 405;
break;
case $e instanceof UnauthorizedHttpException:
$msg = 'Verification failed';
$state = $code = 422;
break;
case $e instanceof HttpException:
$msg = $e->getMessage();
switch ($e->getStatusCode()) {
case 401:
$state = $code = 401;
break;
default:
$code = $e->getStatusCode();
break;
}
}
return responseHelper(false, $msg, $state, $code);
});
}
})->create();
推荐文章: