Exceptions และ Error ในภาษา JavaScript
ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับการจัดการข้อผิดพลาดในภาษา JavaScript ที่เรียกว่า Exception handling มันเป็นวิธีที่จะทำให้โปรแกรมไม่หยุดทำงานและยังสามารถทำงานต่อไปนี้ นอกข้อนี้เราจะพูดถึงข้อผิดพลาดมาตฐานในภาษา JavaScript นี่เป็นเนื้อหาในบทนี้
- Exception คืออะไร
- การใช้งานคำสั่ง try catch
- การ throw ข้อผิดพลาด
- การใช้งานคำสั่ง finally
- การสร้างคสาส Error แบบกำหนดเอง
- Standard error ในภาษา JavaScript
Exception คืออะไร
Exception คือรูปแบบของการจัดการข้อผิดพลาด (Error) ที่เกิดขึ้นในโปรแกรม ด้วยคำสั่ง try catch เพื่อกำหนดข้อยกเว้นเพื่อให้โปรแกรมยังคงสามารถทำงานต่อไปได้เมื่อเกิดข้อผิดพลาดขึ้น โดยปกติแล้วเมื่อเกิดข้อผิดพลาดขึ้นในขณะที่โปรแกรมทำงาน จะส่งผลให้โปรแกรมหยุดทำงานในทันที เราสามารถป้องกันเหตุการณ์นี้ได้โดยการตรวจจับและจัดการกับข้อผิดพลาดดังกล่าว ซึ่งวิธีการนี้เรียกว่า Exception handing
ข้อผิดพลาดเป็นเรื่องปกติที่สามารถเกิดขึ้นได้ในการเขียนโปรแกรม และมันสามารถเกิดขึ้นได้จากหลายสาเหตุ นี่เป็นตัวอย่างของโปรแกรมที่ทำให้เกิดข้อผิดพลาดเมื่อเรียกใช้ฟังก์ชันที่ไม่ได้ประกาศหรือไม่มีอยู่
noFunction();
console.log("Success");
และนี่เป็นผลลัพธ์การทำงานของโปรแกรม เมื่อโค้ดนี้ถูกรัน
noFunction();
^
ReferenceError: noFunction is not defined
ในการเรียกใช้งานฟังก์ชัน noFunction
นั้นจะทำให้เกิดข้อผิดพลาดขึ้น เนื่องจากฟังก์ชันดังกล่าวยังไม่ได้ถูกประกาศ นั่นส่งผลให้โปรแกรมหยุดทำงาน และแสดงผลเกี่ยวกับข้อผิดพลาดที่เกิดขึ้นออกมาแทน นั่นส่งผลให้คำสั่งที่เหลือ เช่น console.log
จะไม่ถูกทำงาน
นั่นหมายความว่าเมื่อเกิดข้อผิดพลาดขึ้น โปรแกรมจะหยุดทำงานคำสั่งที่เหลือหลังจากนั้น ซึ่งนี่ไม่ใช่สิ่งที่เราต้องการ ในภาษา JavaScript นั้นเราสามารถตรวจสอบข้อผิดพลาดที่เกิดขึ้นเพื่อจัดการกับมันได้โดยการใช้คำสั่ง try catch
การใช้งานคำสั่ง try catch
คำสั่ง try catch นั้นเป็นคำสั่งที่ใช้สำหรับกำหนดบล็อคเพื่อตรวจสอบและจัดการกับข้อผิดพลาดที่อาจจะเกิดขึ้นในโปรแกรม นั่นหมายความว่าเมื่อข้อผิดพลาดเกิดขึ้นในบล็อคของคำสั่ง try โปรแกรมจะไม่หยุดทำงาน และมันปลอดภัยสำหรับเราที่จะจัดการกับข้อผิดพลาดในบล็อคของคำสั่ง catch นี่เป็นรูปแบบการใช้งาน
try {
// Try to do something that may cause errors
} catch (error) {
// Handing errors
}
ในบล็อคของคำสั่ง try
เป็นส่วนที่เราจะเขียนโค้ดที่อาจทำให้เกิดข้อผิดพลาดขึ้น และเมื่อเกิดข้อผิดพลาดขึ้น โปรแกรมจะข้ามการทำงานไปที่บล็อคของคำสั่ง catch
แทน พร้อมส่งพารามิเตอร์ error
ซึ่งเป็นออบเจ็คของข้อผิดพลาดไปยังบล็อคที่เราสามารถใช้ตรวจสอบเกี่ยวกับข้อผิดพลาดได้
แต่ถ้าไม่มีข้อผิดพลาดเกิดขึ้นภายในบล็อคของคำสั่ง try
โปรแกรมข้ามการทำงานในบล็อคของคำสั่ง catch
ไป และทำงานคำสั่งที่เหลือหลังจากบล็อค try catch ต่อไป
นี่เป็นการเรียกใช้ฟังก์ชันที่ไม่มีอยู่เหมือนกับในตัวอย่างก่อนหน้า แต่ในตัวอย่างนี้ เราได้ตรวจสอบและจัดการข้อผิดพลาดด้วยคำสั่ง try catch เพื่อป้องกันไม่ให้โปรแกรมหยุดทำงาน
try {
noFunction();
} catch (error) {
console.log("Error name: " + error.name);
console.log("Error message: " + error.message);
}
console.log("Success");
เมื่อโปรแกรมพบกับบล็อคของคำสั่ง try
จะทำงานภายในบล็อคดังกล่าว ถ้าหากไม่มีข้อผิดพลาดเกิดขึ้นภายในบล็อค โปรแกรมออกจากบล็อคและข้ามการทำงานบล็อคคำสั่ง catch
แต่ถ้าหากมีข้อผิดพลาดเกิดขึ้น ในกรณีนี้เราได้เรียกใช้ฟังก์ชัน noFunction
ซึ่งไม่มีอยู่ นั่นทำให้โปรแกรมข้ามการทำงานไปยังบล็อคของคำสั่ง catch
ทันที พร้อมกับส่งพารามิเตอร์ error
ซึ่งเป็นออบเจ็คเกี่ยวกับข้อผิดพลาดที่เกิดขึ้น
console.log("Error name: " + error.name);
console.log("Error message: " + error.message);
โดยทั่วไปแล้วออบเจ็คข้อผิดพลาดในภาษา JavaScript นั้นเป็นออบเจ็คจากคลาส Error
ที่มี Property name
และ message
ที่สามารถใช้รับเอาชื่อและคำอธิบายเกี่ยวกับข้อผิดพลาดได้ ในตัวอย่างนี้ วิธีที่เราจัดการกับข้อผิดพลาดก็คือแสดงรายละเอียดของข้อผิดพลาดที่เกิดขึ้น
console.log("Success");
เมื่อจบการทำงานของบล็อคคำสั่ง try catch โปรแกรมทำงานคำสั่งที่เหลือนอกบล็อคต่อไป ในกรณีนี้คือการแสดงข้อความออกทางหน้าจอ
การ throw ข้อผิดพลาด
โดยทั่วไปแล้วข้อผิดพลาดที่เกิดขึ้นในภาษา JavaScript นั้นเป็นข้อผิดพลาดมาตรฐานของภาษา ซึ่งมันเกิดขึ้นอัตโนมัติเมื่อ JavaScript engine ไม่สามารถจัดการกับการทำงานบางอย่างได้ ในตัวอย่างก่อนหน้า การเรียกใช้ฟังก์ชันที่ไม่มีอยู่ทำให้เกิดข้อผิดพลาด ReferenceError
ขึ้น ซึ่งนี่เป็นข้อผิดพลาดมาตรฐานของภาษา
ในภาษา JavaScript เราสามารถสั่งให้โปรแกรมเกิดข้อผิดพลาดขึ้นเองได้ โดยการใช้คำสั่ง throw
ซึ่งจะส่งผลให้โปรแกรมหยุดทำงานถ้าไม่มีตรวจสอบ และจัดการกับข้อผิดพลาดด้วยคำสั่ง try catch นี่เป็นรูปแบบการใช้งาน
throw expression;
ในการใช้งานคำสั่ง throw
จะตามด้วย expression
ซึ่งเป็นออบเจ็คของข้อผิดพลาดที่จะถูกส่งไปยังบล็อค catch
เมื่อมีการกำหนด ซึ่งมันสามารถเป็นค่าใดๆ ในภาษา JavaScript แต่โดยทั่วไปแล้วมักจะเป็นออบเจ็คจากคลาส Error
หรือออบเจ็คจากคลาสที่สืบทอดมาจากคลาส Error
นี่เป็นตัวอย่างของโปรแกรมหารตัวเลข และการใช้คำสั่ง throw
เพื่อทำให้เกิดข้อผิดพลาดขึ้นในกรณีที่ตัวหารเป็นศูนย์ แทนที่จะปล่อยให้โปรแกรมทำงานและได้ผลลัพธ์ที่ไม่ถูกต้อง เราสามารถสั่งให้โปรแกรมเกิดข้อผิดพลาดขึ้นเพื่อหยุดการทำงานนั้นได้
let a = 10;
let b = 0;
if (b == 0) {
throw new Error("Cannot be divided by Zero");
}
console.log(`${a} / ${b} = ${a / b}`);
นี่เป็นผลลัพธ์การทำงาของโปรแกรม
throw new Error("Cannot be divided by Zero");
^
Error: Cannot be divided by Zero
ในตัวอย่าง ข้อผิดพลาดจะเกิดขึ้นก็ต่อเมื่อค่าในตัวแปร b
เท่ากับ 0
เพราะว่าในทางคณิตศาสตร์ ตัวเลขไม่สามารถหารด้วยศูนย์ได้ ดังนั้นเราได้ทำให้เกิดข้อผิดพลาดขึ้นด้วยคำสั่ง throw
นี่จะทำให้โปรแกรมหยุดทำงานถ้าไม่ถูกจัดการด้วยคำสั่ง try catch
throw new Error("Cannot be divided by Zero");
คำสั่ง throw
จะทำให้เกิดข้อผิดพลาดขึ้น เราสร้างออบเจ็คจากคลาส Error
ซึ่งเป็นออบเจ็คของข้อผิดพลาดในครั้งนี้ และเราสามารถกำหนดข้อความเกี่ยวกับข้อผิดพลาดที่ต้องการได้ผ่านทางคอนสรัตเตอร์ของคลาส
การ throw
ข้อผิดพลาดนั้นเป็นการออกแบบโปรแกรมเพื่อให้แน่ใจว่ามันจะทำงานในรูปแบบที่ต้องการเท่านั้น ถ้าหากมีเงื่อนไขบางอย่างที่อาจทำให้โปรแกรมไม่สามารถทำงานได้ เราสามารถทำให้เกิดข้อผิดพลาดได้ด้วยคำสั่ง throw
ข้อผิดพลาดที่เกิดขึ้นจากคำสั่ง throw
นั้นสามารถตรวจสอบได้โดยคำสั่ง try catch เหมือนกับที่ทำไปในตัวอย่างก่อนหน้า คุณสามารถจินตนาการได้ว่ามันเป็นข้อผิดพลาดที่รอการจัดการ ไม่เช่นนั้นโปรแกรมจะหยุดทำงาน
แนวคิดของการทำให้เกิดข้อผิดพลาดนั้นมีประโยชน์มากในการเขียนโปรแกรม มันเป็นสิ่งที่ช่วยยืนยันได้ว่าโปรแกรมจะทำงานอย่างถูกต้องและในขอบเขตที่กำหนดเท่านั้น ต่อไปมาดูตัวอย่างสำหรับฟังก์ชันหาค่า Factorial ของตัวเลข โดยการ throw ข้อผิดพลาดเมื่อพารามิเตอร์ที่ส่งเข้ามาในฟังก์ชันไม่ถูกต้อง
function factorial(n) {
if (n < 0) {
throw new Error("Number must not negative to find factorial");
}
if (n > 15) {
throw new Error("Number is too large to find factorial");
}
let fac = 1;
for (let i = 1; i <= n; i++) {
fac *= i;
}
return fac;
}
let numbers = [3, 5, -1, 20];
for (let num of numbers) {
try {
console.log(`${num}! = ${factorial(num)}`);
} catch (error) {
console.log(error.message);
}
}
นี่เป็นผลลัพธ์การทำงานของโปรแกรม
3! = 6
5! = 120
Number must not negative to find factorial
Number is too large to find factorial
ในตัวอย่างนี้ แสดงวิธีการทำให้เกิดข้อผิดพลาดด้วยคำสั่ง throw
โดยฟังก์ชัน factorial
ซึ่งเป็นฟังก์ชันสำหรับหาค่า Factorial ของตัวเลข โดยค่า Factorial ของตัวเลขจำนวนเต็ม n หรือ n! นั้นคือผลลัพธ์จากการคูณกันของตัวเลขตั้งแต่ 1 ถึง n ยกเว้น 0! ที่มีค่าเป็น 1
if (n < 0) {
throw new Error("Number must not negative to find factorial");
}
if (n > 15) {
throw new Error("Number is too large to find factorial");
}
เนื่องจากการหาค่า Factorial จะทำกับตัวเลขจำนวนเต็มบวกและศูนย์เท่านั้น ดังนั้นเมื่อค่าที่่ส่งเข้ามาน้อยกว่า 0
เราทำให้เกิดข้อผิดพลาดด้วยคำสั่ง throw
และนอกจากนี้ตัวเลขสูงสุดที่ส่งเข้ามาจะต้องไม่เกิน 15 ด้วย นี่เพื่อเป็นสิ่งที่จะยืนยันว่าในการใช้งานฟังก์ชันจะต้องใช้กับตัวเลขที่กำหนดเท่านั้น นั่นก็คือ 0 - 15
นั่นเอง
let numbers = [3, 5, -1, 20];
for (let num of numbers) {
try {
console.log(`${num}! = ${factorial(num)}`);
} catch (error) {
console.log(error.message);
}
}
ในการใช้งานฟังก์ชัน factorial
เราควรจะตรวจสอบการทำงานด้วยคำสั่ง try catch เพื่อให้แน่ใจว่าเมื่อเกิดข้อผิดพลาดเกิดขึ้น โปรแกรมจะจัดการกับมันและทำงานต่อไปได้ ในกรณีนี้เมื่อเกิดข้อผิดพลาดขึ้นสำหรับพารามิเตอร์ -1
และ 20
เราได้แสดงข้อความเกียวกับข้อผิดพลาดจาก error.message
เมื่อเราใช้คำสั่ง try เพื่อครอบการทำงานของโค้ด มันตรวจจับทุกขอผิดพลาดที่เกิดขึ้นภายในบล็อคดังกล่าวเท่านั้น ทั้งข้อผิดพลาดที่เกิดโดยภาษา JavaScript เอง หรือข้อผิดพลาดที่เกิดขึ้นจากคำสั่ง throw
นี่เป็นตัวอย่างของโปรแกรมที่ข้อผิดพลาดประเภทต่างๆ สามารถเกิดขึ้นได้ในบล็อคของคำสั่ง try
let select = 3;
try {
switch (select) {
case 1:
console.log(foo);
break;
case 2:
noFunction();
break;
case 3:
throw new Error("This is my error");
case 4:
throw new RangeError("Range error");
}
} catch (error) {
if (error instanceof ReferenceError) {
console.log("Use undefined variable or function");
} else if (error instanceof Error) {
console.log(error.message);
} else if (error instanceof RangeError) {
console.log("Range error occured");
} else {
throw error
}
}
ในตัวอย่าง เป็นการจำลองโปรแกรมที่สามารถทำให้เกิดข้อผิดพลาดประเภทต่างๆ ขึ้นได้ในบล็อคคำสั่ง try
เราสามารถเลือกได้ว่าต้องการให้ข้อผิดพลาดใดเกิดขึ้นโดยการกำหนดค่า 1 - 3
ในตัวแปร select
ไม่ว่าข้อผิดพลาดประเภทใดจะเกิดขึ้น คำสั่ง try
สามารถตรวจจับได้ทั้งหมดและส่งต่อการทำงานไปยังบล็อคของคำสั่ง catch
พร้อมกับออบเจ็ค error
ของข้อผิดพลาดดังกล่าว
if (error instanceof ReferenceError) {
console.log("Use undefined variable or function");
} else if (error instanceof Error) {
console.log(error.message);
} else if (error instanceof RangeError) {
console.log("Range error occured");
} else {
throw error
}
เมื่อข้อผิดพลาดในตัวแปร error
สามารถเป็นได้หลายประเภท เราสามารถใช้ตัวดำเนินการ instanceof
สำหรับตรวจสอบประเภทของข้อผิดพลาด เพื่อจัดการกับข้อผิดพลาดแต่ละประเภทในวิธีที่เหมาะสมได้ต่อไป
throw error
และในบล็อคของคำสั่ง else
เราสามารถ throw
ข้อผิดพลาดในบล็อคของคำสั่ง catch
ได้ นั่นจะทำให้ข้อผิดพลาดนี้ถูกตรวจจับในบล็อคของคำสั่ง try
ที่อยู่สูงกว่า (ถ้าหากมี) มันเป็นวิธีที่ดีที่เราควรจะจัดการเพียงข้อผิดพลาดที่รู้จักเท่านั้น ในกรณีที่ไม่รู้จักการทำการ rethrow มัน
การใช้งานคำสั่ง finally
คำสั่ง finally ใช้สำหรับกำหนดบล็อคเพื่อให้โปรแกรมทำงานบางอย่างเมื่อการจัดการข้อผิดพลาดจบลง กล่าวคือคำสั่งในบล็อค finally
จะทำงานเสมอไม่ว่าจะเกิดข้อผิดพลาดขึ้นหรือไม่ และมันใช้ร่วมกับคำสั่ง try catch นี่เป็นรูปแบบการใช้งาน
try {
// Do something
} catch (error) {
// Handing error
} finally {
// Always execute this block
}
เมื่อโปรแกรมทำงานในบล็อคของคำสั่ง try
โดยไม่มีข้อผิดพลาด จากนั้นจะทำงานในบล็อค finally
ต่อ ในขณะที่มีข้อผิดพลาดเกิดขึ้นในบล็อคของคำสั่ง try
โปรแกรมข้ามมาทำงานในบล็อคของคำสั่ง catch
จากนั้นจะทำงานในบล็อค finally
เช่นกัน
ดังนั้นมันจึงมักจะใช้สำหรับกำหนดเพื่อให้โปรแกรมทำงานบางอย่าง ไม่ว่าจะเกิดข้อผิดพลาดหรือไม่ก็ตาม เช่น การคืนทรัพยาการให้กับระบบ การปิดไฟล์ หรือปิดการเชื่อมต่อฐานข้อมูล เป็นต้น
ในตัวอย่างนี้แสดงการใช้งานคำสั่ง finally
ในภาษา JavaScript สำหรับการเรียกใช้งานเมธอดที่ไม่มีอยู่บนออบเจ็ค
let user = {
id: 1,
name: "Metin"
};
function sayHi(user) {
console.log(`Hi ${user.name}!`);
}
try {
user.sayHi();
} catch (error) {
console.log(error.message);
sayHi(user);
} finally {
console.log("Method has been called");
}
นี่เป็นผลลัพธ์การทำงานของโปรแกรม
user.sayHi is not a function
Hi Metin!
Method has been called
เมื่อโปรแกรมรันและทำงานในบล็อคของคำสั่ง try
นั่นทำให้เกิดข้อผิดพลาดขึ้นเนื่องจากเราเรียกใช้งานเมธอดที่ไม่มีอยู่บนออบเจ็ค user
เมื่อมันเกิดขึ้น โปรแกรมข้ามการทำงานไปยังบล็อคของคำสั่ง catch
console.log(error.message);
sayHi(user);
ในบล็อคของคำสั่ง catch
เราจัดการข้อผิดพลาดโดยการเรียกใช้งานฟังก์ชัน sayHi
เพื่อแสดงชื่อในออบเจ็คแทน นี่เป็นวิธีที่เราแก้ปัญหาเมื่อเมธอด sayHi
ไม่มีอยู่บนออบเจ็ค user
นั่นหมายความว่าเมธอดถูกเรียกใช้สำเร็จเสมอ ไม่วิธีใดก็วิธีหนึ่ง
ในบล็อคของคำสัง finally
เราสามารถกำหนดการทำงานเพื่อให้ทำงานเสมอไม่ว่าจะเกิดข้อผิดพลาดหรือไม่ นั่นเป็นเพราะว่าเราได้จัดการการเรียกใช้เมธอดในบล็อคของคำสั่ง catch
แล้ว ดังนั้นเราแสดงข้อความว่าเมธอดถูกเรียกใช้สำเร็จ
console.log("Method has been called");
ขอบเขตตัวแปร: คำสั่ง try catch และ finally มีขอบเขตตัวแปรเป็นของมันเอง นั่นหมายความว่าตัวแปรที่ประกาศภายในบล็อคจะสามารถเข้าถึงได้จากโค้ดภายในบล็อค หรือบล็อคที่อยู่ภายในมันเท่านั้น
การสร้างคสาส Error แบบกำหนดเอง
ในตัวอย่างนี้จะเป็นการสร้างคลาสข้อผิดพลาดแบบกำหนดเอง ทุกข้อผิดพลาดที่เกิดขึ้นในภาษา JavaScript นั้นเป็นออบเจ็คจากคลาส Error
ซึ่งคลาสนี้มี Property และเมธอดพื้นฐานที่สำคัญที่อธิบายเกี่ยวกับข้อผิดพลาด
ในภาษา JavaScript เราสามารถสร้างคลาสข้อผิดพลาดของเราเองได้โดยการสืบทอดจากคลาส Error
นี่จะทำให้เราสามารถเข้าถึง Property และเมธอดพื้นฐานเกี่ยวกับข้อผิดพลาดได้ ในขณะที่ยังสามารถเพิ่มการทำงานบางอย่างของเราเองเข้ามา
นี่เป็นตัวอย่างของการสร้างคลาสข้อผิดพลาดสำหรับจัดการกับการเข้าสู่ระบบที่ไม่ถูกต้อง
class LoginError extends Error {
constructor(username, password) {
super("Invalid username or password");
this.name = "LoginError";
this.username = username;
this.password = password;
}
info() {
console.log("Login failed with");
console.log("Username: " + this.username);
console.log("Password: " + "*".repeat(this.password.length));
}
log() {
// Maybe to log invalid attempt to logging service
console.log("Send log to logging service...");
}
}
let username = "metin";
let password = "1234";
try {
if (username == "metin" && password == "secret") {
console.log("Login success!");
} else {
throw new LoginError(username, password);
}
} catch (error) {
console.log(error.toString());
error.info();
error.log();
}
นี่เป็นผลลัพธ์การทำงานของโปรแกรม
LoginError: Invalid username or password
Login failed with
Username: metin
Password: ****
Send log to logging service...
ในตัวอย่าง เราได้สร้างคลาสข้อผิดพลาด LoginError
ซึ่งเป็นคลาสของข้อผิดพลาดที่จะถูก throw เมื่อการเข้าสู่ระบบไม่ประสบความสำเร็จ คลาสนี้สืบทอดมาจากคลาส Error
ซึ่งเป็นคลาสข้อผิดพลาดของภาษา JavaScript
constructor(username, password) {
super("Invalid username or password");
this.name = "LoginError";
this.username = username;
this.password = password;
}
คอนสตรัคเตอร์ของคลาสรับค่าสองพารามิเตอร์ username
และ password
ที่ทำให้เกิดข้อผิดพลาดขึ้น เราเรียกใช้งานคอนสตรัคเตอร์ของคลาส Error
เพื่อกำหนดคำอธิบายข้อผิดพลาดใหม่ และเปลี่ยนชื่อข้อผิดพลาดเป็น "LoginError"
และกำหนด Property ให้กับคลาสจากพารามิเตอร์ที่รับเข้ามา
info() {
console.log("Login failed with");
console.log("Username: " + this.username);
console.log("Password: " + "*".repeat(this.password.length));
}
log() {
// Maybe to log invalid attempt to logging service
console.log("Send log to logging service...");
}
ภายในคลาสเราได้สร้างเมธอดเพิ่มเติมสองเมธอด เมธอด info
ใช้แสดงรายละเอียดเกี่ยวกับข้อผิดพลาด และเมธอด log
นั้นเป็นเมธอดที่จำลองการเก็บบักทึกการเข้าสู่ระบบที่ล้มเหลวไปยัง ยกตัวอย่างเช่น Service สำหรับการเก็บ Log
throw new LoginError(username, password);
ในบล็อคของคำสั่ง try
เราได้จำลองการทำงานเพื่อให้เกิดข้อผิดพลาดขึ้น โดยกำหนดให้ชื่อผู้ใช้และรหัสผ่านผิด และทำการ throw ข้อผิดพลาด โดยการสร้างออบเจ็คข้อผิดพลาดจากคลาส LoginError
โดยส่งชื่อผู้ใช้และรหัสผ่านเข้าไป
...
} catch (error) {
console.log(error.toString());
error.info();
error.log();
}
จากนั้นในบล็อคของคำสั่ง catch
เป็นการจัดการข้อผิดพลาดที่เกิดขึ้นตามปกติ แต่ในตอนนี้เราสามารถเรียกใช้งานเมธอดที่เราสร้างขึ้นได้ เนื่องจากมันเป็นออบเจ็คจากคลาส LoginError
ที่ได้ถูก throw มา สังเกตว่าเรายังคงสามารถเรียกใช้เมธอด toString
ซึ่งเป็นเมธอดจากคลาส Error
ที่สืบทอดมาได้
คุณสามารถสร้างคลาสข้อผิดพลาดโดยไม่สืบทอดจากคลาสข้อผิดพลาดมาตฐานของภาษาได้ แต่คุณจะสูญเสียการเข้าถึง Property และเมธอดพื้นฐานที่สำคัญ โดยทั่วไปแล้วข้อปฏิบัติในการออกแบบคลาสข้อผิดพลาดควรมี Property name
และ message
และเมธอด toString
ซึ่งคุณจะต้องทำทั้งหมดนี้ด้วยตัวเอง และนั่นเป็นวิธีที่ไม่แนะนำ
Standard error ในภาษา JavaScript
เมื่อเกิดข้อผิดพลาดขึ้นในภาษา JavaScript โปรแกรมจะทำการ throw ข้อผิดพลาดโดยข้อผิดพลาดเหล่านั้นเป็นออบเจ็คจากคลาส Error
หรือคลาสย่อยของมัน ซึ่งคลาสเหล่านี้ประกอบไปด้วย Property เกี่ยวกับข้อผิดพลาดที่เกิดขึ้นที่เราสามารถเรียกดูได้ ดังนี้
message
: ข้อความอธิบายข้อผิดพลาดที่เกิดขึ้นname
: ชื่อของข้อผิดพลาดที่เกิดขึ้น โดยทั่วแล้วมักจะเป็นชื่อของคลาสfileName
: ไฟล์ที่โปรแกรมรันอยู่ในขณะที่เกิดข้อผิดพลาดขึ้นlineNumber
: บรรทัดที่ทำให้เกิดข้อผิดพลาดขึ้นcolumnNumber
: คอลัมน์ในบรรทัดที่ทำให้เกิดข้อผิดพลาดขึ้นstack
: ลำดับสแต็กการทำงานของฟังก์ชันเมื่อเกิดข้อผิดพลาดขึ้น
นี่เป็น Property ที่เราสามารถเข้าถึงได้จากออบเจ็คของข้อผิดพลาดที่เกิดขึ้นในภาษา JavaScript ยกตัวอย่างเช่น
try {
foo
} catch (error) {
// Standrd property
console.log("Error name: " + error.name);
console.log("Error message: " + error.message);
console.log("toString: " + error.toString());
// Non Standrd property
console.log(error.fileName);
console.log(error.lineNumber);
console.log(error.columnNumber);
console.log(error.stack);
}
นี่เป็นผลลัพธ์ในการทำงานของโปรแกรม
Error name: ReferenceError
Error message: foo is not defined
toString: ReferenceError: foo is not defined
undefined
undefined
undefined
ReferenceError: foo is not defined
at Object.<anonymous> (C:\marcuscode\javascript\exceptions\error.js:2:5)
at Module._compile (internal/modules/cjs/loader.js:1256:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
at Module.load (internal/modules/cjs/loader.js:1105:32)
at Function.Module._load (internal/modules/cjs/loader.js:967:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
นี่เป็นการแสดงรายละเอียดเกี่ยวกับข้อผิดพลาดที่เกิดขึ้น สังเกตว่าคุณจะเห็นค่าจากบาง Property ที่เป็น undefinded
เช่น fileName
, lineNumber
หรือ columnNumber
นั่นเป็นเพราะว่า Property เหล่านี้ไม่สนับสนุนโดย Node.js แต่มันอาจสนับสนุนโดยสภาพแวดล้อมการทำงานอื่นๆ เช่น เว็บบราวน์เซอร์
และนี่เป็นรายการของคลาสข้อผิดพลาดมาตรฐานทั้งหมดในภาษา JavaScript ในการทำงานที่ผิดพลาดต่างๆ คลาสเหล่านี้สืบทอดมาจากคลาส Error
เราสามารถสร้างคลาสโดยสืบทอดจากคลาสเหล่านี้ หรือนำมาสร้างออบเจ็คเพื่อ throw ข้อผิดพลาดได้
EvalError
: ข้อผิดพลาดเกี่ยวกับการอ่านโค้ดที่ไม่ถูกต้องของภาษา JavaScript ด้วยฟังก์ชันeval
RangeError
: ข้อผิดพลาดเกี่ยวกับช่วงของข้อมูลไม่ถูกต้องReferenceError
: ข้อผิดพลาดเมื่อใช้งานชื่อของตัวแปรหรือฟังก์ชันที่ไม่ได้ถูกประกาศเอาไว้SyntaxError
: ข้อผิดพลาดเกี่ยวกับโครงสร้างของโปรแกรมไม่ถูกต้องTypeError
: ข้อผิดพลาดเกี่ยวกับการใช้ข้อมูลผิดประเภทURIError
: ข้อผิดพลาดเกี่ยวกับ URL ไม่ถูกต้องเมือแปลง URL ด้วยฟังก์ชันencodeURI
หรือdecodeURI
ซึ่งคลาสเหล่านี้เป็นคลาสที่สืบทอดมาจากคลาส Error
และมันมี Property ที่เราได้อธิบายไปแล้วก่อนหน้า และเราสามารถใช้มันในการสร้างออบเจ็คของข้อผิดพลาด นี่เป็นตัวอย่างของการทำให้เกิดข้อผิดพลาดมาตฐานในภาษา JavaScript
noFunction();
// Output: ReferenceError: noFunction is not defined
เมื่อเรารันโค้ดนี้ ข้อผิดพลาด ReferenceError
จะถูก throw อัตโนมัติโดยตัวแปรของภาษาหรือ JavaScript engine อย่างไรก็ตาม เราสามารถใช้คลาสเหล่านี้เพื่อสร้างออบเจ็คของข้อผิดพลาดและ throw ด้วยตัวเองได้ ยกตัวอย่างเช่น
let value = 20;
if (value < 0 || value > 10) {
throw new RangeError("Invalid value only 1 - 10 allowed.");
}
// Output: RangeError: Invalid value only 1 - 10 allowed.
ในตัวอย่างนี้เราได้ทำการ throw RangeError
เพื่อบ่งบอกว่าเกิดข้อผิดพลาดเกี่ยวกับช่วงของตัวเลข เราสามารถใช้คลาสของภาษา JavaScript ที่มีอยู่มาสร้างออบเจ็คของข้อผิดพลาดได้ การใช้งานคลาสที่มีอยู่แล้วจะทำให้เราได้รับคุณสมบัติและสามารถใช้งานเมธอดบางอย่างโดยที่ไม่ต้องเขียนขึ้นใหม่
ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ Exception และ Error ในภาษา JavaScript เราได้พูดถึงการจัดการข้อผิดพลาดด้วยคำสั่ง try catch และ finally การสร้างคลาสของข้อผิดพลาดที่สืบทอดจากคลาส Error
และเรียนรู้เกี่ยวกับคลาส Error มาตฐานของภาษา ซึ่งเป็นวิธีที่จะรับมือกับข้อผิดพลาดที่อาจเกิดขึ้นในโปรแกรมของเราและจัดการกับมันอย่างถูกต้อง