Skip to main content

เนื้อหาภาษาไทย / Thai content

System guide Content reviewed

การสร้าง Custom Exception

บทความนี้กล่าวถึงความสำคัญของการจัดการข้อผิดพลาดใน API และแนะนำการสร้าง Custom Exception ใน PHP เพื่อให้สามารถระบุชนิดของข้อผิดพลาดได้อย่างละเอียดและจัดการได้อย...

การสร้าง Custom Exception

ในโลกของการพัฒนา API การจัดการข้อผิดพลาด (Error Handling) เป็นสิ่งสำคัญอย่างยิ่ง เพราะ API ที่ดีต้องสามารถแจ้งให้ผู้ใช้งานทราบได้ว่าเกิดอะไรขึ้นเมื่อมีปัญหา และต้องให้ข้อมูลที่เพียงพอต่อการแก้ไขปัญหาเหล่านั้น การใช้ Exception เป็นวิธีที่นิยมในการจัดการข้อผิดพลาดใน PHP แต่บางครั้ง Exception ที่มีอยู่ (เช่น Exception, InvalidArgumentException) อาจไม่เพียงพอที่จะสื่อถึงปัญหาที่เกิดขึ้นในบริบทของ API ของเรา การสร้าง Custom Exception จึงเป็นทางเลือกที่ดีกว่า เพราะช่วยให้เราสามารถกำหนดชนิดของข้อผิดพลาดได้อย่างละเอียดและจัดการกับมันได้อย่างเหมาะสม

Custom Exception คืออะไร

Custom Exception คือ Class ที่เราสร้างขึ้นเองโดยสืบทอด (Inherit) จาก Class Exception หรือ Class อื่นๆ ที่เป็น Exception อยู่แล้ว (เช่น RuntimeException, LogicException) การทำเช่นนี้ทำให้ Custom Exception ของเรามีคุณสมบัติพื้นฐานของ Exception ทั่วไป (เช่น message, code, file, line) แต่เราสามารถเพิ่มคุณสมบัติและเมธอดเฉพาะเจาะจงที่เกี่ยวข้องกับปัญหาที่ต้องการจัดการได้

เหตุผลที่ควรใช้ Custom Exception:

  • ความชัดเจน: ช่วยให้โค้ดอ่านง่ายและเข้าใจง่ายขึ้น เพราะชื่อของ Exception จะสื่อถึงปัญหาที่เกิดขึ้นอย่างชัดเจน
  • การจัดการข้อผิดพลาดที่เฉพาะเจาะจง: ช่วยให้เราสามารถเขียน catch block ที่จัดการกับ Exception ประเภทนั้นๆ ได้โดยเฉพาะ ทำให้การจัดการข้อผิดพลาดมีความละเอียดและแม่นยำมากขึ้น
  • การแยก Concern: ช่วยแยก Concern ของการจัดการข้อผิดพลาดออกจาก Logic หลักของโปรแกรม ทำให้โค้ดมีความ Modular และ Maintainable มากขึ้น

การสร้าง Custom Exception

การสร้าง Custom Exception ใน PHP ทำได้ง่ายมาก เพียงแค่สร้าง Class ใหม่และสืบทอดจาก Class Exception ตัวอย่างเช่น หากเราต้องการสร้าง Exception สำหรับกรณีที่ API Key ไม่ถูกต้อง เราสามารถทำได้ดังนี้:

<?php

class InvalidApiKeyException extends Exception
{
    protected $message = 'Invalid API Key provided.';
    protected $code = 401; // HTTP Status Code: Unauthorized

    public function __construct($message = null, $code = null, Throwable $previous = null)
    {
        if ($message !== null) {
            $this->message = $message;
        }
        if ($code !== null) {
            $this->code = $code;
        }

        parent::__construct($this->message, $this->code, $previous);
    }
}

คำอธิบาย Code:

  • class InvalidApiKeyException extends Exception: ประกาศ Class InvalidApiKeyException ซึ่งสืบทอดจาก Class Exception
  • protected $message = 'Invalid API Key provided.';: กำหนดข้อความ Default สำหรับ Exception นี้
  • protected $code = 401;: กำหนด HTTP Status Code ที่เหมาะสมสำหรับ Exception นี้ (Unauthorized)
  • __construct(): Constructor ของ Class ที่สามารถรับข้อความและ Code ที่กำหนดเองได้ หากไม่มีการส่งค่าเข้ามา จะใช้ค่า Default ที่กำหนดไว้
  • parent::__construct($this->message, $this->code, $previous);: เรียก Constructor ของ Class แม่ (Exception) เพื่อกำหนดค่า message, code และ Throwable (Exception ก่อนหน้า)

Trade-offs: การกำหนด $message และ $code เป็น protected ทำให้ Class ลูกสามารถเข้าถึงและแก้ไขค่าเหล่านี้ได้ แต่ Class ภายนอกไม่สามารถเข้าถึงได้โดยตรง ซึ่งเป็นแนวทางปฏิบัติที่ดีในการ Encapsulation

เราสามารถสร้าง Custom Exception อื่นๆ ได้ในลักษณะเดียวกัน เช่น:

<?php

class ResourceNotFoundException extends Exception
{
    protected $message = 'Resource not found.';
    protected $code = 404; // HTTP Status Code: Not Found
}

class DatabaseConnectionException extends Exception
{
    protected $message = 'Failed to connect to the database.';
    protected $code = 500; // HTTP Status Code: Internal Server Error
}

การใช้งาน Custom Exception

เมื่อเราสร้าง Custom Exception แล้ว เราสามารถใช้มันใน Code ของเราได้โดยการ throw Exception นั้นๆ เมื่อเกิดข้อผิดพลาดที่เกี่ยวข้อง ตัวอย่างเช่น:

<?php

function validateApiKey(string $apiKey): bool
{
    // สมมติว่ามีการตรวจสอบ API Key ในฐานข้อมูล
    if ($apiKey !== 'valid_api_key') {
        throw new InvalidApiKeyException();
    }

    return true;
}

try {
    $apiKey = $_GET['api_key'] ?? '';
    validateApiKey($apiKey);

    // Logic ของ API ที่นี่
    echo "API Key is valid. Processing request...\n";

} catch (InvalidApiKeyException $e) {
    // ส่ง JSON Response กลับไปพร้อม Error Message และ HTTP Status Code
    http_response_code($e->getCode());
    header('Content-Type: application/json');
    echo json_encode([
        'error' => $e->getMessage(),
        'code' => $e->getCode()
    ]);
    exit;
} catch (Exception $e) {
    // จัดการ Exception อื่นๆ ที่อาจเกิดขึ้น
    http_response_code(500);
    header('Content-Type: application/json');
    echo json_encode([
        'error' => 'Internal Server Error',
        'message' => $e->getMessage(),
        'code' => 500
    ]);
    exit;
}

คำอธิบาย Code:

  • validateApiKey(): Function ที่ตรวจสอบ API Key และ throw InvalidApiKeyException หาก API Key ไม่ถูกต้อง
  • try...catch: Block ที่ใช้ดักจับ Exception ที่อาจเกิดขึ้น
  • catch (InvalidApiKeyException $e): Block ที่จะทำงานเมื่อ InvalidApiKeyException ถูก throw
  • http_response_code($e->getCode());: กำหนด HTTP Status Code ตาม Code ที่กำหนดไว้ใน Exception
  • json_encode(): สร้าง JSON Response ที่มี Error Message และ Code

แนวปฏิบัติที่ดี:

  • ระบุ HTTP Status Code ที่ถูกต้อง: การกำหนด HTTP Status Code ที่ถูกต้องใน Custom Exception จะช่วยให้ Client เข้าใจถึงประเภทของข้อผิดพลาดที่เกิดขึ้นได้ง่ายขึ้น
  • ให้ข้อมูลที่เพียงพอ: Error Message ควรให้ข้อมูลที่เพียงพอต่อการแก้ไขปัญหา แต่ไม่ควรเปิดเผยข้อมูลที่ละเอียดอ่อน
  • Logging: ควร Log Exception ที่เกิดขึ้น เพื่อใช้ในการ Debug และ Monitor API
  • Catch Exception ที่เฉพาะเจาะจง: พยายาม Catch Exception ที่เฉพาะเจาะจงเท่าที่จะเป็นไปได้ เพื่อให้การจัดการข้อผิดพลาดมีความแม่นยำมากขึ้น

การสร้าง Custom Exception เป็นเครื่องมือที่มีประโยชน์อย่างมากในการจัดการข้อผิดพลาดใน API ช่วยให้เราสามารถกำหนดชนิดของข้อผิดพลาดได้อย่างละเอียดและจัดการกับมันได้อย่างเหมาะสม ทำให้ API ของเรามีความแข็งแกร่งและเชื่อถือได้มากยิ่งขึ้น

Office.in.th Custom Service

Want to build or adapt a system from this structure?

Office.in.th designs and develops enterprise web applications, API integrations, and public- and private-sector management systems, with long-term support.

See our software development service