معالجة الأخطاء في Javascript & Typescript
عندما يحدث خطأ في وقت التشغيل ، يتم "طرحه" في Javascript و Typescript ، كما هو الحال في معظم لغات البرمجة. ستؤدي أخطاء القذف التي لم تتم معالجتها إلى تعطل التطبيق أو الخدمة ، وبالتالي إلى أسوأ تجربة ممكنة للمستخدم. في حالة حدوث خطأ ، يتم فقد أي تقدم غير محفوظ وقد يبدأ المستخدمون عملية طويلة (على سبيل المثال ، إذا كان المستخدم يسجل في نظام أساسي من خلال توفير الكثير من المعلومات) مرة أخرى. والنتيجة هي أن هؤلاء المستخدمين لن يستخدموا منتجك مرة أخرى على الأرجح ، حيث فقدت الثقة.
للتعامل مع مثل هذه الحالات ، يمكن "اكتشاف" خطأ. للقبض على الأخطاء في Javascript و Typescript ، يمكنك ببساطة تغليف الكود الخاص بك في "try" -block ، متبوعًا بـ "catch" -block.
async function getData(){
try {
// Call a dummy async 'fetch'-functoin
const result = await fetch();
return { result };
} catch(error) {
return { error };
}
}
// ... later in your code ....
const { result, error } = await getData();
if (error){
// ... handle error case.
}
// Access the results.
والنتيجة هي أن الخطأ لن ينتشر عبر النظام بأكمله ، مما يؤدي إلى التعطل ، ولكن سيتم التعامل معه مباشرة في نطاق التعليمات البرمجية الخاصة بك. لن يتعطل التطبيق أو الخدمة ويمكن تطبيق إستراتيجية التخفيف لمعالجة الخطأ.
التعامل الخاص مع الكتلة "أخيرًا"
كخطوة إضافية للتعامل مع الأخطاء ، توفر Javascript و Typescript كلمة رئيسية إضافية "أخيرًا". ينفذ مثل هذا الحظر "أخيرًا" أي كود ضمن نطاقه بعد تنفيذ كل من كتلة "try" و "catch" (في حالة حدوث خطأ).
// This function is absolutely save
// to call. It fetches some data and
// optionally catches a potential error.
//
// After everything's done, a 'finally'
// sends the error to our backend for logs,
// if there was any.
async function getData(){
// In this case, we store the result
// and error in mutable variables,
// then return both.
let result: Result;
let error: Error;
try {
// Call a dummy async 'fetch'-function
result = await fetch();
} catch(e) {
error = e;
} finally {
// After the whole try/catch has been
// processed, we can log the error.
if(error){
await trackErrorInCloud(error);
}
}
return { result, error };
}
// ... same as before ...
ولكن انتظر هناك المزيد! هل تعلم أنه يتم تنفيذ الكتلة "أخيرًا" حتى إذا قمت بإرجاع نتيجة في الكتلة "try" - أو "catch"؟ هذا مثال على ما أعنيه بذلك.
// Same as the example before, but
// now we directly return from within
// each code block. And this is where
// a side effect can happen.
async function getData(){
try {
const result = await fetch();
return { result };
} catch(error) {
return { error }
} finally {
//
// WATCH OUT!
//
// Just for demo purpose, but this
// line of code will override both
// the return in 'try' as well as 'catch'!
//
// Returning inside of 'finally' is therefore
// dangerous and will lead to hard-to-debug
// issues.
return { finally: true };
}
}
// data === { finally: true }
const data = await getData();
// Here's a better use case for
// finally.
async function getData(){
let error: Error;
try {
const result = await fetch();
return { result };
} catch(e) {
error = e;
return { error }
} finally {
// No return in finally,
// so it's safe to use.
if(error){
await logInCloud()
}
}
}
// if no error === { result: ... }
// if error === { error: ... }
const data = await getData();
ملخص
كما رأيت ، يعد التعامل مع الأخطاء في Javascript و Typescript أمرًا سهلاً للغاية ويتجنب حدوث تعطل كامل لتطبيقك. من الجيد معرفة المعالجة الخاصة للنتائج المرتجعة في الكتل "try" - و "catch" - عند استخدام كتلة "أخيرًا" ، ولكن لا ينبغي إساءة استخدامها لتجنب تنفيذ التعليمات البرمجية بأسلوب مضاد للنمط.