0Pricing
Kotlin Academy · บทเรียน

การสร้างคลาส Exception แบบกำหนดเอง

กำหนด exception เฉพาะโดเมนพร้อมข้อความและพร็อพเพอร์ตีที่สื่อความหมาย

การสร้างคลาส Exception แบบกำหนดเอง เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องใช้ข้อยกเว้นแบบกำหนดเอง

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

ข้อยกเว้นแบบกำหนดเองที่เรียบง่ายที่สุด

สืบทอดจาก Exception หรือคลาสย่อยเฉพาะ เช่น RuntimeException แล้วส่งข้อความให้ตัวสร้างของคลาสแม่

class InvalidEmailException(message: String) : Exception(message)
fun main() {
    try {
        throw InvalidEmailException("missing @")
    } catch (e: InvalidEmailException) {
        println("caught: ${e.message}")
    }
}

ข้อยกเว้นที่มีคุณสมบัติ

เพิ่มฟิลด์เพื่อสื่อบริบท เช่น สถานะ HTTP ชื่อฟิลด์ และจำนวนครั้งที่ลองใหม่

class HttpError(
    message: String,
    val statusCode: Int
) : Exception(message)
fun main() {
    try {
        throw HttpError("Not Found", 404)
    } catch (e: HttpError) {
        println("HTTP ${e.statusCode}: ${e.message}")
    }
}

ข้อยกเว้นที่มีสาเหตุ

ส่ง cause เพื่อเก็บข้อยกเว้นเดิมไว้ในสายโซ่

class DatabaseError(message: String, cause: Throwable) : Exception(message, cause)
fun main() {
    try {
        try { error("connection refused") }
        catch (e: Throwable) { throw DatabaseError("query failed", e) }
    } catch (e: DatabaseError) {
        println("${e.message} (caused by: ${e.cause?.message})")
    }
}

ตรวจสอบกับไม่ตรวจสอบ

Kotlin ถือว่าข้อยกเว้นทั้งหมดเป็นแบบไม่ตรวจสอบ โดยไม่จำเป็นต้องประกาศ throws ตามธรรมเนียมจึงมักสืบทอดจาก RuntimeException

class ValidationException(field: String, message: String) :
    RuntimeException("[$field] $message")
fun main() {
    try {
        throw ValidationException("age", "must be positive")
    } catch (e: ValidationException) {
        println(e.message)
    }
}

ลำดับชั้นของข้อยกเว้นในโดเมน

สร้างลำดับชั้นเพื่อให้ผู้เรียกสามารถดักจับชนิดพื้นฐานสำหรับการจัดการทั่วไป หรือใช้ชนิดย่อยเฉพาะสำหรับกรณีพิเศษ

open class AppException(message: String) : RuntimeException(message)
class NotFoundException(what: String) : AppException("$what not found")
class UnauthorizedException : AppException("not authorized")
fun main() {
    val errors = listOf(NotFoundException("user"), UnauthorizedException())
    for (e in errors) {
        try { throw e }
        catch (e: AppException) { println("App error: ${e.message}") }
    }
}

ลำดับชั้นข้อยกเว้นแบบปิด

สำหรับชุดชนิดข้อผิดพลาดที่กำหนดตายตัว ให้ใช้ลำดับชั้นแบบ sealed เพื่อให้ผู้เรียกจัดการตัวเลือกต่าง ๆ ได้ครบถ้วน

sealed class ApiError(message: String) : RuntimeException(message) {
    class Timeout : ApiError("timeout")
    class NotFound(val id: String) : ApiError("not found: $id")
    class ServerError(val status: Int) : ApiError("server returned $status")
}
fun describe(e: ApiError) = when (e) {
    is ApiError.Timeout -> "request timed out"
    is ApiError.NotFound -> "id ${e.id} missing"
    is ApiError.ServerError -> "5xx: ${e.status}"
}
fun main() {
    println(describe(ApiError.NotFound("user-42")))
}

หลักการตั้งชื่อ

ลงท้ายชื่อคลาสข้อยกเว้นแบบกำหนดเองด้วย Exception หรือ Error เพื่อความชัดเจน ใช้รูปอดีตกาลหรือคำนาม เช่น NotFound และ InvalidInput

class InvalidInputException(msg: String) : RuntimeException(msg)
class UserNotFoundException(id: Int) : RuntimeException("user $id not found")
fun main() {
    try { throw UserNotFoundException(7) }
    catch (e: UserNotFoundException) { println(e.message) }
}

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

ใช้เอกสารประกอบโค้ด @throws เพื่อระบุว่าฟังก์ชันอาจโยนข้อยกเว้นใด

/**
 * @throws InvalidEmailException if the email is malformed
 */
fun validate(email: String) {
    if ("@" !in email) throw InvalidEmailException("missing @")
}
class InvalidEmailException(m: String) : RuntimeException(m)
fun main() {
    try { validate("nope") }
    catch (e: InvalidEmailException) { println(e.message) }
}

หลีกเลี่ยงการใช้ข้อยกเว้นมากเกินไป

ข้อยกเว้นมีไว้สำหรับสถานการณ์ที่ผิดไปจากปกติ สำหรับผลลัพธ์ที่คาดหมายได้ เช่น ข้อมูลเข้าว่างหรือฟิลด์เสริมไม่มีค่า ควรเลือกการส่งคืนค่าแบบ nullable ชนิดผลลัพธ์แบบปิด หรือค่าเริ่มต้น

fun findUser(id: Int): String? = if (id == 1) "Alice" else null
fun main() {
    val name = findUser(42) ?: "(unknown)"
    println(name) // (unknown), no exception
}

ตัวอย่างเชิงปฏิบัติ

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

class ApiException(
    message: String,
    val statusCode: Int,
    val responseBody: String
) : RuntimeException(message)
fun main() {
    try {
        throw ApiException("Bad Request", 400, "{\"error\":\"invalid\"}")
    } catch (e: ApiException) {
        println("[${e.statusCode}] ${e.message}: ${e.responseBody}")
    }
}

ตรวจสอบอย่างรวดเร็ว

โดยทั่วไปแล้ว คลาสแม่ใดใช้บ่อยที่สุดเมื่อกำหนดข้อยกเว้น Kotlin เฉพาะโดเมน

สรุปทบทวน

ข้อยกเว้นแบบกำหนดเองเข้ารหัสความหมายของโดเมน ให้สืบทอดจาก RuntimeException หรือ Exception เพิ่มคุณสมบัติเพื่อเก็บบริบท รักษาสาเหตุเดิม และสร้างลำดับชั้นเพื่อจัดกลุ่มการดักจับ ใช้ข้อยกเว้นแบบปิดสำหรับชุดที่กำหนดตายตัว และเลือกชนิด nullable หรือชนิดผลลัพธ์เมื่อข้อผิดพลาดเป็นสิ่งที่คาดหมายได้

คำถามที่พบบ่อย

บทเรียน “การสร้างคลาส Exception แบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างคลาส Exception แบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างคลาส Exception แบบกำหนดเอง”

กำหนด exception เฉพาะโดเมนพร้อมข้อความและพร็อพเพอร์ตีที่สื่อความหมาย คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การสร้างคลาส Exception แบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. try/catch/finally ในฐานะนิพจน์
  2. การสร้างคลาส Exception แบบกำหนดเอง
  3. runCatching และ Result
  4. การโยน Exception ซ้ำและการเชื่อมโยง Exception
← กลับไปที่ Kotlin Academy