جافا سكريبت/تايب سكريبت: الطريقة القياسية للاحتفاظ بسبب الخطأ


لدي خلفية كمطور جافا وأنا جديد إلى حد ما في جافاسكريبت/تايبسكريبت.

هل هناك طريقة قياسية لإدارة والحفاظ على سبب الخطأ في JavaScript/TypeScript؟

هدفي هو الحصول على تتبع كامل للأخطاء عندما أقوم بتغليف خطأ داخل آخر؛ قليلاً كما هو الحال مع تتبع استثناءات جافا:

Message of exception 1
...
Caused by: Message of exception 2
...
Caused by: Message of the root exception

جربت هذا الكود لكن err1 لا يحتفظ بالمرجع الخاص بـ err2:

// CODE
try {
    try {
        throw new Error("Error no2");
    } catch (err2) {
        console.log("========================================");
        console.log(err2);
        throw new Error("Error no1");
    }
} catch (err1) {
    console.log("========================================");
    console.log(err1);
}
// CONSOLE OUTPUT
node test.ts 
========================================
Error: Error no2
    at Object.<anonymous> (/tmp/test.ts:3:15)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
    at internal/main/run_main_module.js:17:11
========================================
Error: Error no1
    at Object.<anonymous> (/tmp/test.ts:7:15)
    at Module._compile (internal/modules/cjs/loader.js:956:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
    at internal/main/run_main_module.js:17:11

علاوة على ذلك، لا أجد أي خاصية باسم cause في فئة Error. هناك خاصية stack ولكن أعتقد أنه من السيئ تغييرها.

شكراً!

الإجابة رقم 1

جواب 2021: يوجد الآن طريقة معيارية لإدارة والحفاظ على سبب الخطأ. يمكن لمُنشئ Error() الآن قبول كائن options كمعامل ثانٍ. يجب أن يحتوي كائن options هذا على خاصية cause والتي عادةً ما تكون خطأ Error آخر لكنها ليست مضطرة لذلك.

مثال

throw new Error('Outer Error', {cause: new Error('Inner Error')});

دعم

في وقت كتابة هذا النص (أكتوبر 2021) هناك دعم للباني الجديد في فايرفوكس، كروم وسفاري. للحصول على سبب Error ستحتاج إلى استجواب خاصيته cause. بالإضافة إلى ذلك، في فايرفوكس نحصل على بعض المعلومات الإضافية في وحدة التحكم، على سبيل المثال

Uncaught Error: Outer Error
    <anonymous> debugger eval code:1
Caused by: Error: Inner Error
    <anonymous> debugger eval code:1

سيقوم متصفح إيدج حالياً بتجاهل خاصية الباني الثانية فقط.

المصادر

وثائق موزيلا: https://developer.mozilla.org/en-US/docs/web/javascript/reference/global_objects/error

اقتراح ECMAScript: https://github.com/tc39/proposal-error-cause