บทนำ
ข้อยกเว้นและข้อผิดพลาดมักจะเกิดขึ้นในขณะที่ผู้ใช้โต้ตอบกับแอปพลิเคชันใดๆ ก็ตาม ขึ้นอยู่กับวิศวกรซอฟต์แวร์ที่จะเลือกวิธีจัดการกับข้อผิดพลาดใดๆ ที่อาจเกิดขึ้นไม่ว่าจะโดยเจตนาหรือโดยไม่รู้ตัว ด้วยเหตุนี้ นักพัฒนาระบบแบ็คเอนด์ที่สร้าง API ด้วย Express พบว่าตนเองทำงานเพื่อให้แน่ใจว่าพวกเขากำลังสร้าง API ที่มีประโยชน์ มีประสิทธิภาพ และใช้งานได้ สิ่งที่สำคัญที่สุดคือการจัดการกับข้อผิดพลาดในลักษณะที่จะสร้างระบบที่มีประสิทธิภาพ เพราะสิ่งนี้จะช่วยลดเวลาในการพัฒนา ข้อผิดพลาดทันที ปัญหาด้านประสิทธิภาพ และเป็นตัวกำหนดความสำเร็จหรือความสามารถในการปรับขนาดของการพัฒนาซอฟต์แวร์
คุณต้องบันทึกข้อความแสดงข้อผิดพลาด ระงับข้อผิดพลาด แจ้งผู้ใช้เกี่ยวกับข้อผิดพลาด หรือเขียนโค้ดเพื่อจัดการกับข้อผิดพลาดหรือไม่ ไม่ต้องแปลกใจอีกต่อไป.
ในคู่มือนี้ เราจะเรียนรู้วิธีสร้างโค้ดเบสการจัดการข้อผิดพลาดที่มีประสิทธิภาพสำหรับแอปพลิเคชัน Express ซึ่งจะทำหน้าที่ในการช่วยตรวจหาข้อผิดพลาดของแอปพลิเคชันและดำเนินการที่เหมาะสมที่สุดเพื่อกู้คืนแอปพลิเคชันใดๆ จากความล้มเหลวอย่างงดงามในระหว่างรันไทม์
หมายเหตุ เราจะใช้ Postman เพื่อทดสอบ API ในการสาธิตของเรา สามารถดาวน์โหลดได้ที่ หน้าดาวน์โหลดบุรุษไปรษณีย์. หรือคุณสามารถใช้เบราว์เซอร์ บรรทัดคำสั่ง curl
เครื่องมือหรือเครื่องมืออื่น ๆ ที่คุณอาจคุ้นเคย
การจัดการข้อผิดพลาดคืออะไร?
ในการพัฒนาซอฟต์แวร์ มีข้อยกเว้นสองประเภท: การดำเนินงาน และ การเขียนโปรแกรม.
- ความล้มเหลวในการดำเนินงานอาจเกิดขึ้นระหว่างรันไทม์ และเพื่อป้องกันไม่ให้แอปพลิเคชันหยุดทำงานกะทันหัน เราต้องจัดการกับข้อยกเว้นเหล่านี้อย่างสง่างามด้วยวิธีการจัดการข้อผิดพลาดที่มีประสิทธิภาพ
- โปรแกรมเมอร์ส่งข้อยกเว้นทางโปรแกรมด้วยตนเอง เมื่อมีสถานะพิเศษเกิดขึ้น
คุณอาจคิดว่าข้อยกเว้นในการปฏิบัติงานเป็นข้อยกเว้นที่ "คาดไม่ถึง แต่คาดการณ์ไว้ล่วงหน้า" (เช่น การเข้าถึงดัชนีนอกขอบเขต) และข้อยกเว้นทางโปรแกรมเป็นข้อยกเว้น "คาดไว้และมองเห็นล่วงหน้า" (เช่น ข้อยกเว้นการจัดรูปแบบตัวเลข)
การจัดการข้อยกเว้นเป็นขั้นตอนที่ใช้ในการค้นหาและแก้ไขข้อบกพร่องภายในโปรแกรม การจัดการข้อผิดพลาดจะส่งข้อความที่มีประเภทของข้อผิดพลาดที่เกิดขึ้นและสแต็กที่เกิดข้อผิดพลาด
หมายเหตุ ในวิทยาการคอมพิวเตอร์ ข้อยกเว้นสามารถกู้คืนได้จาก และโดยทั่วไปเกิดจากปัญหาด้านการปฏิบัติงานหรือทางโปรแกรมในระหว่างรันไทม์ ข้อผิดพลาดมักเกิดขึ้นจากปัจจัยภายนอก เช่น ข้อจำกัดของฮาร์ดแวร์ ปัญหาเกี่ยวกับการเชื่อมต่อ หน่วยความจำไม่เพียงพอ ฯลฯ ใน JavaScript คำศัพท์นี้มักจะใช้แทนกันได้ และข้อยกเว้นที่กำหนดเองได้มาจาก Error
ชั้นเรียน Error
คลาสนั้นแสดงทั้งข้อผิดพลาดและข้อยกเว้น
ใน Express การจัดการข้อยกเว้นหมายถึงวิธีที่ Express ตั้งค่าให้ตรวจจับและประมวลผลข้อยกเว้นแบบซิงโครนัสและอะซิงโครนัส ข้อดีเกี่ยวกับการจัดการข้อยกเว้นใน Express คือ ในฐานะนักพัฒนา คุณไม่จำเป็นต้องเขียนตัวจัดการข้อยกเว้นของคุณเอง Express มาพร้อมกับตัวจัดการข้อยกเว้นเริ่มต้น ตัวจัดการข้อยกเว้นช่วยในการระบุข้อผิดพลาดและรายงานให้ผู้ใช้ทราบ นอกจากนี้ยังมีกลยุทธ์การแก้ไขที่หลากหลายและนำไปใช้เพื่อลดข้อยกเว้น
แม้ว่าสิ่งเหล่านี้อาจดูเหมือนมีหลายสิ่งที่อยู่ภายใต้ประทุน แต่การจัดการข้อยกเว้นใน Express ไม่ได้ทำให้กระบวนการโดยรวมของโปรแกรมช้าลงหรือหยุดการดำเนินการชั่วคราว
ทำความเข้าใจเกี่ยวกับการจัดการข้อยกเว้นใน Express
ด้วยตัวจัดการข้อผิดพลาดเริ่มต้นที่มาพร้อมกับ Express เรามีชุดฟังก์ชันมิดเดิลแวร์ในมือของเราที่ช่วยจับข้อผิดพลาดในตัวจัดการเส้นทางโดยอัตโนมัติ เร็วๆ นี้ เราจะสร้างโครงการเพื่อนำทฤษฎีไปปฏิบัติจริงเกี่ยวกับวิธีส่งคืนข้อผิดพลาดที่เหมาะสมในแอป Express และวิธีไม่ให้ข้อมูลที่ละเอียดอ่อนรั่วไหล
การกำหนดฟังก์ชันมิดเดิลแวร์ใน Express
ฟังก์ชันมิดเดิลแวร์การจัดการข้อผิดพลาดถูกกำหนดในลักษณะที่ยอมรับ Error
ออบเจกต์เป็นพารามิเตอร์อินพุตแรก ตามด้วยพารามิเตอร์เริ่มต้นของฟังก์ชันมิดเดิลแวร์อื่นๆ: request
, response
และ next
. next()
ฟังก์ชันจะข้ามมิดเดิลแวร์ปัจจุบันทั้งหมดไปยังตัวจัดการข้อผิดพลาดถัดไปสำหรับเราเตอร์
การตั้งค่าการจัดการข้อผิดพลาดใน Express
เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัลเพื่อสร้างแอป Node และ Express:
$ mkdir error-handling-express
ในโฟลเดอร์ที่สร้างขึ้นใหม่ มาเริ่มต้นโครงการ Node ใหม่กัน:
$ cd error-handling-express && npm init -y
สิ่งนี้จะสร้างไฟล์ package.json
ไฟล์ในโฟลเดอร์ของเรา
หากต้องการสร้างเซิร์ฟเวอร์ Express ในแอป Node ของเรา เราต้องติดตั้ง express
แพคเกจ, dotenv
สำหรับการโหลดตัวแปรสภาพแวดล้อมโดยอัตโนมัติ .env
ไฟล์เข้า process.env
วัตถุและ nodemon
สำหรับการรีสตาร์ทแอปโหนดหากบันทึกการเปลี่ยนแปลงไฟล์ในไดเร็กทอรี
$ npm install express dotenv nodemon
ถัดไป สร้างไฟล์ app.js
ไฟล์ในโฟลเดอร์โครงการซึ่งจะทำหน้าที่เป็นไฟล์ดัชนีสำหรับแอป
ตอนนี้เราได้ติดตั้งการอ้างอิงที่จำเป็นทั้งหมดสำหรับแอป Express ของเราแล้ว เราจำเป็นต้องตั้งค่าสคริปต์สำหรับอ่านแอปใน package.json
ไฟล์. เพื่อให้บรรลุเป้าหมายดังกล่าว package.json
ไฟล์เพื่อให้ไฟล์ scripts
วัตถุดังที่แสดงด้านล่าง:
"scripts": {
"start": "nodemon app.js"
},
หรือคุณสามารถข้ามการใช้ nodemon
และใช้ node app.js
แทน.
การตั้งค่าเซิร์ฟเวอร์ Express
ในการตั้งค่าเซิร์ฟเวอร์นั้น เราต้อง import package ต่างๆ เข้าไปก่อน app.js
. เรายังจะสร้าง .env
ไฟล์ในไดเร็กทอรีโครงการ - เพื่อเก็บตัวแปรสภาพแวดล้อมทั้งหมดสำหรับแอปพลิเคชัน:
const express = require('express')
require('dotenv').config
PORT=4000
เราได้กำหนดหมายเลขพอร์ตสำหรับแอปใน .env
ที่โหลดเข้ามาอ่านโดย dotenv
และสามารถเข้าถึงได้ในภายหลัง
การเริ่มต้นเซิร์ฟเวอร์ด่วน
ตอนนี้ เราจำเป็นต้องเริ่มต้นเซิร์ฟเวอร์ Express และทำให้แอปของเราฟังหมายเลขพอร์ตของแอป พร้อมกับคำขอไปยังเส้นทางทดสอบ – /test
. มาอัพเดทกัน app.js
ใต้คำสั่งนำเข้า:
const app = express();
const port = process.env.PORT || 4000;
app.get("/test", async (req, res) => {
return res.status(200).json({ success: true });
});
app.listen(port, () => {
console.log(`Server is running at port ${port}`);
});
จากนี้ไป เราจะเรียนรู้วิธีจัดการกับกรณีการใช้งานต่างๆ ของข้อผิดพลาดในการดำเนินงานที่อาจเกิดขึ้นใน Express
การจัดการไม่พบข้อผิดพลาดใน Express
สมมติว่าคุณต้องการดึงข้อมูลผู้ใช้ทั้งหมดจากฐานข้อมูลของผู้ใช้ คุณสามารถจัดการกับสถานการณ์ข้อผิดพลาดที่อาจเกิดขึ้นได้อย่างมีประสิทธิภาพซึ่งไม่มีข้อมูลอยู่ในฐานข้อมูล โดยรวมตรรกะไว้ใน try/catch
บล็อก - หวังว่าจะตรวจจับข้อผิดพลาดที่อาจเกิดขึ้นใน catch
บล็อก:
const getUser = () => undefined;
app.get("/get-user", async (req, res) => {
try {
const user = getUser();
if (!user) {
throw new Error('User not found');
}
} catch (error) {
console.log(error);
res.status(400).send(error.message)
}
return res.status(200).json({
success: true
});
});
ผลลัพธ์นี้ใน:
User not found
ขณะนี้ เมื่อคำขอนี้ถูกสร้างขึ้น (คุณสามารถทดสอบโดยใช้บุรุษไปรษณีย์) และไม่มีผู้ใช้อยู่ในฐานข้อมูล ไคลเอ็นต์จะได้รับข้อความแสดงข้อผิดพลาดที่ระบุว่า "ไม่พบผู้ใช้" นอกจากนี้ คุณจะสังเกตเห็นว่าข้อผิดพลาดถูกบันทึกไว้ในคอนโซลด้วย
เพิ่มประสิทธิภาพการจัดการข้อผิดพลาดด้วย Error Handler Middleware
เราสามารถเพิ่มประสิทธิภาพการพัฒนาโดยการสร้างมิดเดิลแวร์ตัวจัดการข้อผิดพลาดที่จะมาถึงจุดสิ้นสุดของเส้นทางที่กำหนดไว้ทั้งหมด ดังนั้นหากเกิดข้อผิดพลาดในเส้นทางใดเส้นทางหนึ่ง Express จะดูที่มิดเดิลแวร์ถัดไปโดยอัตโนมัติและไล่ตามรายการต่อไป จนกว่าจะถึงตัวจัดการข้อผิดพลาด ตัวจัดการข้อผิดพลาดจะประมวลผลข้อผิดพลาดและส่งการตอบกลับไปยังไคลเอนต์
ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!
ในการเริ่มต้น ให้สร้างโฟลเดอร์ชื่อ middleware
ในไดเร็กทอรีโปรเจ็กต์ และในโฟลเดอร์นี้ ให้สร้างไฟล์ชื่อ errorHandler.js
ซึ่งกำหนดตัวจัดการข้อผิดพลาด:
const errorHandler = (error, req, res, next) => {
console.log(error);
res.status(400).send(error.message);
}
module.exports = errorHandler;
ในฟังก์ชันมิดเดิลแวร์ของเรา เราได้ทำให้ Express ทราบว่านี่ไม่ใช่ฟังก์ชันมิดเดิลแวร์พื้นฐาน แต่เป็นตัวจัดการข้อผิดพลาด โดยการเพิ่ม error
พารามิเตอร์ก่อน 3 พารามิเตอร์พื้นฐาน
ตอนนี้ เราจะใช้ตัวจัดการข้อผิดพลาดในการสาธิตของเรา app.js
และจัดการข้อผิดพลาดเริ่มต้นของการดึงข้อมูลผู้ใช้ด้วยมิดเดิลแวร์ตัวจัดการข้อผิดพลาด ดังที่แสดงด้านล่าง:
const getUser = () => undefined;
app.get("/get-user", async (req, res, next) => {
try {
const user = getUser();
if (!user) {
throw new Error("User not found");
}
} catch (error) {
return next(error);
}
});
app.use(errorHandler);
เราสามารถปรับปรุงโค้ดของเราให้ดียิ่งขึ้น โดยสร้างสิ่งที่เป็นนามธรรมรอบๆ try/catch
ตรรกะ. เราสามารถทำได้โดยการสร้างโฟลเดอร์ใหม่ในไดเร็กทอรีโครงการที่เรียกว่า utils
และในนั้นให้สร้างไฟล์ชื่อ tryCatch.js
.
เพื่อนามธรรม try-catch
ลอจิก – เราสามารถกำหนดฟังก์ชันที่ยอมรับฟังก์ชันอื่น (เรียกว่า ตัวควบคุม) เป็นพารามิเตอร์และส่งกลับค่า an async
ฟังก์ชันซึ่งจะเก็บ try/catch
สำหรับคอนโทรลเลอร์ที่ได้รับ
หากเกิดข้อผิดพลาดในคอนโทรลเลอร์ ข้อผิดพลาดนั้นจะติดอยู่ใน catch
บล็อกและเรียกใช้ฟังก์ชันถัดไป:
const tryCatch = (controller) => async (req, res, next) => {
try {
await controller(req, res);
} catch (error) {
return next(error);
}
};
module.exports = tryCatch;
กับ try/catch
สิ่งที่เป็นนามธรรม เราสามารถ refactor โค้ดของเราเพื่อให้รวบรัดมากขึ้นโดยข้าม try-catch
ข้ออย่างชัดเจนเมื่อเรียกผู้ใช้ใน app.js
:
const getUser = () => undefined;
app.get(
"/get-user",
tryCatch(async (req, res) => {
const user = getUser();
if (!user) {
throw new Error("User not found");
}
res.status(400).send(error.message);
})
);
เราเลิกใช้ตรรกะ try-catch ได้สำเร็จ และโค้ดของเรายังคงใช้งานได้เหมือนเดิม
การจัดการข้อผิดพลาดการตรวจสอบใน Express
สำหรับการสาธิตนี้ เราจะสร้างเส้นทางใหม่ในแอป Express สำหรับการเข้าสู่ระบบ – เพื่อตรวจสอบ ID ผู้ใช้เมื่อเข้าสู่ระบบ ขั้นแรก เราจะติดตั้ง joi
package เพื่อช่วยในการสร้าง schema ซึ่งเราสามารถบังคับใช้ข้อกำหนดได้:
$ npm i joi
จากนั้นสร้างสคีมาซึ่งเป็น Joi.object
กับ userId
ซึ่งต้องเป็นตัวเลขและจำเป็น หมายความว่าคำขอต้องตรงกับออบเจกต์ที่มี ID ผู้ใช้อยู่
เราสามารถใช้ไฟล์ validate()
วิธีการในวัตถุสคีมาเพื่อตรวจสอบทุกอินพุตกับสคีมา:
const schema = Joi.object({
userId: Joi.number().required(),
});
app.post(
"/login",
tryCatch(async (req, res) => {
const {error, value} = schema.validate({});
if (error) throw error;
})
);
หากมีการส่งผ่านวัตถุเปล่าเข้าไปใน validate()
วิธีการ ข้อผิดพลาดจะได้รับการจัดการอย่างงดงาม และข้อความแสดงข้อผิดพลาดจะถูกส่งไปยังไคลเอ็นต์:
บนคอนโซล เรายังสามารถเข้าถึง details
อาร์เรย์ที่มีรายละเอียดต่างๆ เกี่ยวกับข้อผิดพลาดที่สามารถสื่อสารกับผู้ใช้ได้หากจำเป็น
เพื่อจัดการกับข้อผิดพลาดในการตรวจสอบโดยเฉพาะในลักษณะที่จะส่งรายละเอียดข้อผิดพลาดที่เหมาะสมต่อข้อผิดพลาดในการตรวจสอบ มิดเดิลแวร์ตัวจัดการข้อผิดพลาดสามารถถูกรีแฟคเตอร์ได้:
const errorHandler = (error, req, res, next) => {
console.log(error);
if (error.name === "ValidationError") {
return res.status(400).send({
type: "ValidationError",
details: error.details,
});
}
res.status(400).send(error.message);
};
module.exports = errorHandler;
กับ errorHandler.js
ตอนนี้ปรับแต่งเมื่อเราส่งคำขอเดียวกันกับวัตถุว่างเปล่าที่ส่งไปยัง validate()
วิธี:
ตอนนี้เราสามารถเข้าถึงออบเจกต์แบบกำหนดเองที่ส่งคืนข้อความในลักษณะที่อ่านง่าย/เป็นมิตรมากขึ้น ด้วยวิธีนี้ เราสามารถส่งและจัดการกับข้อผิดพลาดประเภทต่างๆ ตามประเภทของข้อผิดพลาดที่เข้ามา
สรุป
ในคู่มือนี้ เราได้กล่าวถึงการจัดการข้อผิดพลาดของ Express.js ทุกแง่มุม รวมถึงวิธีจัดการโค้ดแบบซิงโครนัสและอะซิงโครนัสตามค่าเริ่มต้น วิธีสร้างคลาสข้อผิดพลาดของคุณเอง วิธีเขียนฟังก์ชันมิดเดิลแวร์การจัดการข้อผิดพลาดแบบกำหนดเอง และจัดเตรียม next
เป็นตัวจัดการจับสุดท้าย
เช่นเดียวกับงานอื่นๆ ที่มีอยู่ นอกจากนี้ยังมีแนวทางปฏิบัติที่ดีที่สุดในระหว่างการพัฒนาซึ่งรวมถึงการจัดการข้อผิดพลาดอย่างมีประสิทธิภาพ และวันนี้เราได้เรียนรู้วิธีจัดการกับข้อผิดพลาดในแอป Express อย่างมีประสิทธิภาพ
การจัดการข้อผิดพลาดอย่างถูกต้องไม่ได้หมายถึงการลดเวลาในการพัฒนาโดยการค้นหาจุดบกพร่องและข้อผิดพลาดอย่างง่ายดาย แต่ยังรวมถึงการพัฒนาโค้ดเบสที่แข็งแกร่งสำหรับแอปพลิเคชันขนาดใหญ่ด้วย ในคู่มือนี้ เราได้เห็นวิธีตั้งค่ามิดเดิลแวร์สำหรับจัดการข้อผิดพลาดในการปฏิบัติงาน วิธีอื่นๆ ในการปรับปรุงการจัดการข้อผิดพลาด ได้แก่ การไม่ส่งสแต็กเทรซ การหยุดกระบวนการอย่างนุ่มนวลเพื่อจัดการกับข้อยกเว้นที่ไม่ถูกตรวจสอบ การให้ข้อความแสดงข้อผิดพลาดที่เหมาะสม การส่งบันทึกข้อผิดพลาด และการตั้งค่าคลาสที่ขยาย Error
ชั้นเรียน
ฉันหวังว่าตัวอย่างที่ฉันใช้ในบทช่วยสอนนี้จะเป็นประโยชน์สำหรับคุณ ฉันได้กล่าวถึงสถานการณ์ต่างๆ ที่คุณอาจพบเมื่อเขียนแอปพลิเคชัน Express เพื่อใช้งานในโลกแห่งความเป็นจริงเกี่ยวกับการจัดการข้อผิดพลาด โปรดแจ้งให้เราทราบหากมีสิ่งใดที่ฉันพลาดไป มันจะเป็นประโยชน์ต่อเราและช่วยให้ฉันเรียนรู้มากขึ้นเช่นกัน ขอให้มีวันที่ดีและขอบคุณสำหรับการอ่าน
คุณสามารถอ้างถึงซอร์สโค้ดทั้งหมดที่ใช้ในบทความเรื่อง Github.