Skip to content

9. خطاها و استثناها

Image

جاوااسکریپت سیستم مدیریت استثنا (exception handling) بسیار پیشرفته‌ای ندارد. با این حال، دستور [throw] را فراهم می‌کند که امکان سیگنال‌دهی خطا را فراهم می‌آورد، و همچنین ساختار try / catch / finally که امکان رهگیری این خطاها را ممکن می‌سازد.

9.1. اسکریپت [excep-01]

در اسکریپت زیر، تاریخ فعلی را در قالب [heures:minutes:secondes:millisecondes] نمایش خواهیم داد. برای این کار، از کتابخانه‌ای به نام jS استفاده خواهیم کرد. ما آن را طبق معمول با استفاده از ابزار [npm] نصب می‌کنیم:

Image

کد اسکریپت به شرح زیر است:


'use strict';

// پکیج moment
import moment from 'moment';

...

برای اینکه بفهمیم چگونه خط [import] را در خط ۴ بنویسیم، می‌توانیم به تعریف ماژول [moment] نگاه کنیم:

Image

  • در [1-2]، به تعریف ماژول می‌رویم؛
  • در [3]، ما یک فایل TypeScript داریم، نه یک فایل JavaScript. در زمان اجرا، این فایل TypeScript قبل از استفاده به یک فایل JavaScript کامپایل می‌شود؛
  • در [4]، ما در [export] به دنبال دستورالعمل‌ها می‌گردیم (Ctrl-F);
  • در [5]، عبارت exports شیء [moment] را صادر می‌کند. این می‌تواند به صورت زیر به ES6 وارد شود:

import moment from 'moment';

می‌توان از هر نامی برای وارد کردن شیء [moment] استفاده کرد، برای مثال:


import m from 'moment';

بیایید به کد اسکریپت بازگردیم:


'use strict';

// پکیج moment
import moment from 'moment';

// اصل try / catch / finally
for (let i = 0; i < 10; i++) {
  // تاریخ و زمان فعلی
  const now = Date.now();
  //قالب‌بندی زمان برای شامل کردن میلی‌ثانیه‌ها
  const time = moment(now).format("HH:mm:ss:SSS");
  // میلی‌ثانیه
  const milli = Number(time.substr(time.length - 3));
  //نمایش
  console.log("--------------------itération n° ", i, "à", time);
  try {
    // عددی که با زمان فعلی تغییر می‌کند
    const nbre = milli % 2;
    if (nbre === 0) {
      // نمایش پیام خطا
      throw "erreur";
    }
    // اگر به این نقطه رسیده‌اید، یعنی هیچ خطایی رخ نداده است
    console.log("pas d'erreur");
  } catch (error) {
    //اگر به این نقطه رسیده‌اید، یعنی خطایی رخ داده است
    console.log("erreur1=", error);
  } finally {
    //در همه موارد اجرا می‌شود، چه خطایی وجود داشته باشد چه نداشته باشد
    console.log("finally")
  }
}

نظرات

  • خط ۴: کتابخانه [moment] را وارد کنید؛
  • اسکریپت ۱۰ بار تکرار می‌شود (خط ۷). در هر تکرار حلقه، زمان فعلی در قالب [heures:minutes:secondes:millisecondes] استخراج می‌شود (خطوط ۸–۱۳)؛
  • اگر تعداد میلی‌ثانیه‌ها زوج باشد، یک پیام خطا نمایش داده می‌شود (خطوط ۱۹–۲۲)؛
  • هدف در اینجا درک نحوه کار بلوک‌های try / catch / finally است

اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\exceptions\excep-01.js"
--------------------itération n° 0 à 17:57:04:440
erreur1= erreur
finally
--------------------itération n° 1 à 17:57:04:447
pas d'erreur
finally
--------------------itération n° 2 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 3 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 4 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 5 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 6 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 7 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 8 à 17:57:04:449
pas d'erreur
finally
--------------------itération n° 9 à 17:57:04:449
pas d'erreur
finally

می‌توانیم ببینیم که بند [finally] همیشه اجرا می‌شود، صرف‌نظر از اینکه خطایی رخ دهد یا خیر.

9.2. اسکریپت [excep-02]

این اسکریپت که می‌تواند توسط عبارت [throw] فراخوانی شود، می‌تواند هر نوع داده‌ای را مدیریت کند و این داده‌ها به‌طور کامل توسط عبارت [catch] بازیابی می‌شوند.


''use strict';

// می‌توانید تقریباً هر چیزی را 'throw' کنید تا خطا را اعلام کنید
let i = 0;
console.log("--------------------essai n° ", i);
// یک رشته را پرتاب کنید
try {
  throw "msg d'erreur";
} catch (error) {
  // یک خطا رخ داده است
  console.log("erreur=[", error, "], type=", typeof (error));
}
//یک جدول ایجاد کنید
i++;
console.log("--------------------essai n° ", i);
try {
  throw [1, 2, 3]
} catch (error) {
  // یک خطا رخ داد
  console.log("erreur=[", error, "], type=", typeof (error));
}
// شیء صریح را تبدیل کنید
i++;
console.log("--------------------essai n° ", i);
try {
  throw { nom: "hercule", pays: "grèce antique" }
} catch (error) {
  // یک خطا رخ داده است
  console.log("erreur=[", error, "], type=", typeof (error));
}
// انداختن یک نوع Error
i++;
console.log("--------------------essai n° ", i);
try {
  throw new Error("erreur de connexion au réseau");
} catch (error) {
  // یک خطا رخ داده است
  console.log("erreur=[", error, "], type=", typeof (error));
}
// پرتاب یک نوع خطا
i++;
console.log("--------------------essai n° ", i);
try {
  throw new Error("erreur de connexion au réseau");
} catch (error) {
  // یک خطا رخ داده است – پیام در [error.message] است
  console.log("erreur.message=[", error.message, "], type(error)=", typeof (error));
}

توضیحات

  • خطوط ۳۵، ۴۴: [Error] یک کلاس جاوااسکریپت است که سازند آن یک پیام خطا را به عنوان پارامتر اول اختیاری می‌پذیرد. این پیام را می‌توان از طریق خاصیت [Error.message] (خط ۴۷) بازیابی کرد؛
  • کلاس‌های دیگری به غیر از [Error] وجود دارند که می‌توان از آن‌ها برای گزارش خطا استفاده کرد: [EvalError, InternalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError);

اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\exceptions\excep-02.js"
--------------------essai n° 0
erreur=[ msg d'erreur ], type= string
--------------------essai n° 1
erreur=[ [ 1, 2, 3 ] ], type= object
--------------------essai n° 2
erreur=[ { nom: 'hercule', pays: 'grèce antique' } ], type= object
--------------------essai n° 3
erreur=[ Error: erreur de connexion au réseau
at Object.<anonymous> (c:\Data\st-2019\dev\es6\javascript\exceptions\excep-02.js:35:9)
at Object.<anonymous> (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:251206)
at c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:245054
at Generator.next (<anonymous>)
at bl (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:245412)
at kl (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:247659)
at Object.u (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:287740)
at Object.o (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:287137)
at Object.<anonymous> (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:284879)
at Object.apply (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:199341) ], type= object
--------------------essai n° 4
erreur.message=[ erreur de connexion au réseau ], type(error)= object

9.3. اسکریپت [excep-03]

این اسکریپت نشان می‌دهد که در یک [catch]، می‌توان نوع نمونه [Error] را که توسط [catch] رهگیری شده است، تشخیص داد:


''use strict';

// پکیج 'moment'
import moment from 'moment';

// تفکیک نمونه خطا دریافت‌شده در یک [catch]
for (let i = 0; i < 10; i++) {
  // تاریخ و زمان فعلی
  const now = Date.now();
  //قالب‌بندی زمان برای درج میلی‌ثانیه‌ها
  const time = moment(now).format("HH:mm:ss:SSS");
  // میلی‌ثانیه
  const milli = Number(time.substr(time.length - 3));
  console.log("--------------------itération n° ", i);
  try {
    // شماره [0, 1, 2]
    const nbre = milli % 3;
    switch (nbre) {
      case 0:
        throw new ReferenceError("erreur 1");
      case 1:
        throw new RangeError("erreur 2");
      default:
        throw new EvalError("erreur 3");
    }
  } catch (error) {
    // یک خطا رخ داده است
    if (error instanceof ReferenceError) {
      console.log("ReferenceError :", error.message);
    } else {
      if (error instanceof RangeError) {
        console.log("RangeError :", error.message);
      }
      else {
        if (error instanceof EvalError) {
          console.log("EvalError :", error.message);
        }
      }
    }
  }
}

اجرا


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\exceptions\excep-03.js"
--------------------itération n° 0
ReferenceError : erreur 1
--------------------itération n° 1
RangeError : erreur 2
--------------------itération n° 2
RangeError : erreur 2
--------------------itération n° 3
RangeError : erreur 2
--------------------itération n° 4
RangeError : erreur 2
--------------------itération n° 5
RangeError : erreur 2
--------------------itération n° 6
EvalError : erreur 3
--------------------itération n° 7
EvalError : erreur 3
--------------------itération n° 8
EvalError : erreur 3
--------------------itération n° 9
EvalError : erreur 3