Xử lý ngoại lệ
Cấu hình
config/exception.php
return [
// Ở đây cấu hình lớp xử lý ngoại lệ
'' => support\exception\Handler::class,
];
Trong chế độ đa ứng dụng, bạn có thể cấu hình riêng lớp xử lý ngoại lệ cho từng ứng dụng, tham khảo đa ứng dụng
Lớp xử lý ngoại lệ mặc định
Trong webman, ngoại lệ mặc định được xử lý bởi lớp support\exception\Handler
. Có thể sửa đổi tệp cấu hình config/exception.php
để thay đổi lớp xử lý ngoại lệ mặc định. Lớp xử lý ngoại lệ phải triển khai giao diện Webman\Exception\ExceptionHandlerInterface
.
interface ExceptionHandlerInterface
{
/**
* Ghi nhận log
* @param Throwable $e
* @return mixed
*/
public function report(Throwable $e);
/**
* Tạo phản hồi
* @param Request $request
* @param Throwable $e
* @return Response
*/
public function render(Request $request, Throwable $e) : Response;
}
Tạo phản hồi
Phương thức render
trong lớp xử lý ngoại lệ được sử dụng để tạo phản hồi.
Nếu giá trị debug
trong tệp cấu hình config/app.php
là true
(sẽ gọi là app.debug=true
), sẽ trả về thông tin ngoại lệ chi tiết, nếu không sẽ trả về thông tin ngoại lệ tóm tắt.
Nếu yêu cầu yêu cầu trả về json, thông tin ngoại lệ sẽ được trả về theo định dạng json, tương tự như
{
"code": "500",
"msg": "Thông tin ngoại lệ"
}
Nếu app.debug=true
, dữ liệu json sẽ có thêm thuộc tính trace
trả về ngăn xếp gọi chi tiết.
Bạn có thể viết lớp xử lý ngoại lệ của riêng mình để thay đổi logic xử lý ngoại lệ mặc định.
Ngoại lệ nghiệp vụ BusinessException
Đôi khi chúng ta muốn dừng yêu cầu trong một hàm lồng ghép và trả về một thông báo lỗi cho khách hàng, lúc này có thể làm điều đó bằng cách ném ra BusinessException
.
Ví dụ:
<?php
namespace app\controller;
use support\Request;
use support\exception\BusinessException;
class FooController
{
public function index(Request $request)
{
$this->chackInpout($request->post());
return response('hello index');
}
protected function chackInpout($input)
{
if (!isset($input['token'])) {
throw new BusinessException('Lỗi tham số', 3000);
}
}
}
Ví dụ trên sẽ trả về một
{"code": 3000, "msg": "Lỗi tham số"}
Lưu ý
Ngoại lệ nghiệp vụ BusinessException không cần phải được cố gắng bắt, framework sẽ tự động bắt và trả về đầu ra phù hợp theo loại yêu cầu.
Tự định nghĩa ngoại lệ nghiệp vụ
Nếu phản hồi trên không phù hợp với yêu cầu của bạn, chẳng hạn như muốn thay đổi msg
thành message
, bạn có thể định nghĩa một MyBusinessException
Tạo mới app/exception/MyBusinessException.php
với nội dung như sau
<?php
namespace app\exception;
use support\exception\BusinessException;
use Webman\Http\Request;
use Webman\Http\Response;
class MyBusinessException extends BusinessException
{
public function render(Request $request): ?Response
{
// Yêu cầu json trả về dữ liệu json
if ($request->expectsJson()) {
return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
}
// Yêu cầu không phải json thì trả về một trang
return new Response(200, [], $this->getMessage());
}
}
Như vậy khi nghiệp vụ gọi
use app\exception\MyBusinessException;
throw new MyBusinessException('Lỗi tham số', 3000);
Yêu cầu json sẽ nhận được một phản hồi json tương tự như sau
{"code": 3000, "message": "Lỗi tham số"}
Mẹo
Bởi vì ngoại lệ BusinessException thuộc về ngoại lệ nghiệp vụ (ví dụ lỗi tham số do người dùng nhập), nó là có thể dự đoán, vì vậy framework sẽ không coi nó là lỗi nghiêm trọng và sẽ không ghi nhận log.
Tóm tắt
Trong bất kỳ trường hợp nào cần ngắt bỏ yêu cầu hiện tại và trả về thông tin cho khách hàng, có thể xem xét sử dụng ngoại lệ BusinessException
.