การจัดการข้อยกเว้น

การตั้งค่า

config/exception.php

return [
    // ที่นี่ตั้งค่าคลาสการจัดการข้อยกเว้น
    '' => support\exception\Handler::class,
];

ในโหมดหลายแอปพลิเคชัน คุณสามารถตั้งค่าคลาสการจัดการข้อยกเว้นสำหรับแต่ละแอปพลิเคชันได้โดยเฉพาะ ดูที่หลายแอปพลิเคชัน

คลาสการจัดการข้อยกเว้นเริ่มต้น

ใน webman ข้อยกเว้นจะถูกจัดการโดยคลาส support\exception\Handler โดยเริ่มต้น คุณสามารถแก้ไขไฟล์การตั้งค่า config/exception.php เพื่อเปลี่ยนคลาสการจัดการข้อยกเว้นเริ่มต้น คลาสการจัดการข้อยกเว้นต้องสร้างอินเตอร์เฟส Webman\Exception\ExceptionHandlerInterface ดังนี้

interface ExceptionHandlerInterface
{
    /**
     * บันทึกบันทึก
     * @param Throwable $e
     * @return mixed
     */
    public function report(Throwable $e);

    /**
     * เรนเดอร์การตอบกลับ
     * @param Request $request
     * @param Throwable $e
     * @return Response
     */
    public function render(Request $request, Throwable $e) : Response;
}

การเรนเดอร์การตอบกลับ

เมธอด render ในคลาสการจัดการข้อยกเว้นจะใช้สำหรับการเรนเดอร์การตอบกลับ

ถ้าไฟล์การตั้งค่า config/app.php มีค่า debug เป็น true (กล่าวถึงในที่นี้ว่า app.debug=true) จะส่งกลับข้อมูลข้อยกเว้นอย่างละเอียด มิฉะนั้นจะส่งกลับข้อมูลข้อยกเว้นอย่างย่อ

ถ้าคำขอคาดหวังว่าจะเป็นการตอบกลับแบบ json จะส่งกลับข้อมูลข้อยกเว้นในรูปแบบ json, คล้ายกับ

{
    "code": "500",
    "msg": "ข้อมูลข้อยกเว้น"
}

ถ้า app.debug=true ข้อมูล json จะมีฟิลด์ trace เพิ่มเติมเพื่อส่งกลับสแต็กการเรียกดูอย่างละเอียด

คุณสามารถเขียนคลาสการจัดการข้อยกเว้นของคุณเองเพื่อเปลี่ยนแปลงตรรกะการจัดการข้อยกเว้นเริ่มต้น

ข้อยกเว้นธุรกิจ BusinessException

บางครั้งเราต้องการที่จะหยุดคำขอในฟังก์ชันที่ซ้อนกันและส่งกลับข้อความผิดพลาดไปยังไคลเอนต์ ในกรณีนี้สามารถทำได้โดยการโยน BusinessException
ตัวอย่างเช่น:

<?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('พารามิเตอร์ไม่ถูกต้อง', 3000);
        }
    }
}

ตัวอย่างข้างต้นจะส่งกลับข้อมูล

{"code": 3000, "msg": "พารามิเตอร์ไม่ถูกต้อง"}

หมายเหตุ
ข้อยกเว้นธุรกิจ BusinessException ไม่จำเป็นต้องมีการจับในธุรกิจ try, เฟรมเวิร์กจะจับมันอัตโนมัติและส่งคืนผลลัพธ์ที่เหมาะสมตามประเภทคำขอ

ข้อยกเว้นธุรกิจที่กำหนดเอง

ถ้าผลลัพธ์ข้างต้นไม่ตรงกับความต้องการของคุณ เช่น ต้องการเปลี่ยน msg เป็น message คุณสามารถกำหนด MyBusinessException

สร้างไฟล์ใหม่ app/exception/MyBusinessException.php เนื้อหาดังนี้

<?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
    {
        // คำขอ json ส่งกลับข้อมูล json
        if ($request->expectsJson()) {
            return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
        }
        // คำขอที่ไม่ใช่ json ส่งกลับหน้า
        return new Response(200, [], $this->getMessage());
    }
}

ดังนั้นเมื่อธุรกิจเรียกใช้

use app\exception\MyBusinessException;

throw new MyBusinessException('พารามิเตอร์ไม่ถูกต้อง', 3000);

คำขอ json จะได้รับการตอบกลับ json คล้ายกับดังนี้

{"code": 3000, "message": "พารามิเตอร์ไม่ถูกต้อง"}

คำแนะนำ
เนื่องจากข้อยกเว้น BusinessException ถือเป็นข้อยกเว้นทางธุรกิจ (เช่น ข้อผิดพลาดในการป้อนพารามิเตอร์ของผู้ใช้) ซึ่งมันสามารถคาดการณ์ได้ เฟรมเวิร์กจึงไม่ถือว่าเป็นข้อผิดพลาดร้ายแรง และจะไม่บันทึกบันทึก

สรุป

ในทุกครั้งที่ต้องการหยุดคำขอปัจจุบันและส่งกลับข้อมูลไปยังไคลเอนต์ คุณสามารถพิจารณาการใช้ข้อยกเว้น BusinessException