شنبه ۲۹ دي ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش جاوا اسکریپت - مدیریت خطاها و استثناها

سه نوع خطا در برنامه‌نویسی وجود دارد: (الف) خطاهای نحوی، (ب) خطاهای اجرایی و (ج) خطاهای منطقی.

خطاهای نحوی

خطاهای نحوی، که همچنین به خطاهای تجزیه (parsing errors) نیز مشهورند، در زمان کامپایل در زبان‌های برنامه‌نویسی سنتی و در زمان تفسیر در جاوااسکریپت رخ می‌دهند.

به عنوان مثال، خط زیر به دلیل عدم وجود پرانتز بسته‌ای، باعث یک خطای نحوی می‌شود:


<script type = "text/javascript">
   <!--
      window.print(;
   //-->
</script>

زمانی که در جاوااسکریپت یک خطای نحوی رخ می‌دهد، فقط کد موجود در همان رشته کد شامل خطای نحوی تحت تأثیر قرار می‌گیرد و بخش دیگری از کد در رشته‌های دیگر، تحت فرضیه که چیزی در آن‌ها به کد حاوی خطا وابستگی ندارد، اجرا می‌شود.

خطاهای اجرایی

خطاهای اجرایی که همچنین به خطاهای استثناء نیز مشهورند، در زمان اجرا (بعد از کامپایل/تفسیر) رخ می‌دهند.

به عنوان مثال، خط زیر به دلیل درستی نحوی در زمان اجرا خطای اجرایی می‌دهد؛ زیرا در آن سعی می‌شود به یک متد که وجود ندارد، دسترسی پیدا کند:


<script type = "text/javascript">
   <!--
      window.printme();
   //-->
</script>

خطاهای استثنا وقتی رخ می‌دهند تاثیر آنها روی رشته کدی (thread) ایجاد کننده خطاست و رشته‌های دیگر بدون تاثیر بر روی آنها به اجرای معمول خود ادامه می‌دهند.

خطاهای اجرایی (Runtime Errors)

خطاهای اجرایی (runtime errors) یا خطاهای استثنایی در زمان اجرا (پس از ترجمه یا بررسی اولیه) رخ می‌دهند.

برای مثال، در خط زیر خطای اجرایی رخ می‌دهد زیرا در زمان اجرا، سعی در فراخوانی یک متدی که وجود ندارد انجام می‌شود، اما دستورالعمل نوشتاری آن درست است:

خطاهای منطقی (Logical Errors)

خطاهای منطقی ممکن است دشوارترین نوع خطاها باشند که باید پیگیری شوند. این خطاها ناشی از خطای نهادینه شده در منطق برنامه نویسی است و ممکن است باعث عدم دریافت نتیجه مورد انتظار شود.

شما نمی‌توانید این خطاها را به دست بیاورید زیرا بستگی به نیاز کسب‌وکار شما دارد که چه نوع منطق را در برنامه خود قرار می‌دهید.

استفاده از try...catch...finally

آخرین نسخه‌های جاوا اسکریپت امکانات مدیریت استثنا را اضافه کردند. جاوا اسکریپت، ساختار try...catch...finally و همچنین عملگر throw را برای مدیریت خطاها پیاده‌سازی می‌کند.

شما می‌توانید خطاهای تولید شده توسط برنامه‌نویس و خطاهای اجرایی را با استفاده از try...catch بگیرید، اما نمی‌توانید خطاهای نحوی جاوااسکریپت را بگیرید

اینجا نمونه‌ای از دستور بلوک try...catch...finally آمده است −


<script type = "text/javascript">
   <!--
      try {
         // Code to run
         [break;]
      } 
      
      catch ( e ) {
         // Code to run if an exception occurs
         [break;]
      }
      
      [ finally {
         // Code that is always executed regardless of 
         // an exception occurring
      }]
   //-->
</script>

بلوک try باید به دقت یک بلوک catch یا یک بلوک finally (یا هر دو) دنبال شود. هنگامی که یک استثناء در بلوک try اتفاق می افتد، استثناء در e قرار می گیرد و بلوک catch اجرا می شود. بلوک finally اختیاری است و بعد از بلوک try/catch همیشه اجرا می شود.

نمونه ها

اینجا مثالی است که در آن سعی می کنیم تا یک تابع غیر موجود را صدا بزنیم که در نتیجه باعث بروز یک استثناء می شود. بیایید ببینیم بدون استفاده از try...catch چطور رفتار می کند −


<html>
   <head>      
      <script type = "text/javascript">
         <!--
            function myFunc() {
               var a = 100;
               alert("Value of variable a is : " + a );
            }
         //-->
      </script>      
   </head>
   
   <body>
      <p>Click the following to see the result:</p>
      
      <form>
         <input type = "button" value = "Click Me" onclick = "myFunc();" />
      </form>      
   </body>
</html>

حالا بیایید با استفاده از try...catch سعی کنیم این استثناء را بگیریم و پیامی کاربرپسند نمایش دهیم. اگر می‌خواهید این خطا را از کاربر پنهان کنید، می‌توانید این پیام را فرمان‌دهی کنید.


<html>
   <head>
      
      <script type = "text/javascript">
         <!--
            function myFunc() {
               var a = 100;
               try {
                  alert("Value of variable a is : " + a );
               } 
               catch ( e ) {
                  alert("Error: " + e.description );
               }
            }
         //-->
      </script>
      
   </head>
   <body>
      <p>Click the following to see the result:</p>
      
      <form>
         <input type = "button" value = "Click Me" onclick = "myFunc();" />
      </form>
      
   </body>
</html>

شما می‌توانید از بلوک finally استفاده کنید که همیشه بعد از بلوک try/catch بدون قید و شرط اجرا می‌شود. یک مثال اینجا آمده است.


<html>
   <head>
      
      <script type = "text/javascript">
         <!--
            function myFunc() {
               var a = 100;
               
               try {
                  alert("Value of variable a is : " + a );
               }
               catch ( e ) {
                  alert("Error: " + e.description );
               }
               finally {
                  alert("Finally block will always execute!" );
               }
            }
         //-->
      </script>
      
   </head>
   <body>
      <p>Click the following to see the result:</p>
      
      <form>
         <input type = "button" value = "Click Me" onclick = "myFunc();" />
      </form>
      
   </body>
</html>

اعلامیه throw

شما می توانید از دستور throw برای پرتاب استثناء های داخلی یا سفارشی خود استفاده کنید. سپس می توانید این استثنائات را گرفتار کرده و اقدام مناسبی را انجام دهید.

مثال

مثال زیر نحوه استفاده از دستور throw را نشان می دهد.


<html>
   <head>
      
      <script type = "text/javascript">
         <!--
            function myFunc() {
               var a = 100;
               var b = 0;
               
               try {
                  if ( b == 0 ) {
                     throw( "Divide by zero error." ); 
                  } else {
                     var c = a / b;
                  }
               }
               catch ( e ) {
                  alert("Error: " + e );
               }
            }
         //-->
      </script>
      
   </head>
   <body>
      <p>Click the following to see the result:</p>
      
      <form>
         <input type = "button" value = "Click Me" onclick = "myFunc();" />
      </form>
      
   </body>
</html>

می‌توانید از عبارت throw استفاده کنید تا استثناهای داخلی یا سفارشی خود را ایجاد کنید. در ادامه می‌توانید این استثناها را دریافت کرده و اقدامات مناسب را انجام دهید.

دستور throw

مثال

مثال زیر نحوه استفاده از دستور throw را نشان می‌دهد.

شما می‌توانید یک استثنا در یک تابع با استفاده از یک رشته، عدد، بولین یا یک شی ایجاد کرده و سپس می‌توانید این استثنا را در همان تابع (همانند مثال بالا) یا در یک تابع دیگر با استفاده از بلوک try...catch دریافت کنید.

رویداد onerror()

رویداد onerror اولین ویژگی بود که برای رفع خطا در جاوااسکریپت معرفی شد. وقتی در صفحه یک استثنا اتفاق می‌افتد، رویداد error روی شیء window فرستاده می‌شود.


<html>
   <head>
      
      <script type = "text/javascript">
         <!--
            window.onerror = function () {
               alert("An error occurred.");
            }
         //-->
      </script>
      
   </head>
   <body>
      <p>Click the following to see the result:</p>
      
      <form>
         <input type = "button" value = "Click Me" onclick = "myFunc();" />
      </form>
      
   </body>
</html>

رویداد onerror، سه مورد اطلاعات را به منظور شناسایی دقیق مشخصات خطا فراهم می کند -

  • پیام خطا − همان پیامی که مرورگر برای خطای داده شده نمایش می دهد

  • آدرس (URL) − فایلی که خطا رخ داده است

  • شماره خط − شماره خط در آدرس (URL) داده شده که باعث خطا شده است

در اینجا مثالی را نشان می دهیم که نحوه استخراج این اطلاعات را نمایش می دهد.

مثال


<html>
   <head>
   
      <script type = "text/javascript">
         <!--
            window.onerror = function (msg, url, line) {
               alert("Message : " + msg );
               alert("url : " + url );
               alert("Line number : " + line );
            }
         //-->
      </script>
      
   </head>
   <body>
      <p>Click the following to see the result:</p>
      
      <form>
         <input type = "button" value = "Click Me" onclick = "myFunc();" />
      </form>
      
   </body>
</html>

می‌توانید اطلاعات استخراج شده را به هر شکلی که برای خود مناسب می‌دانید، نمایش دهید.

شما می‌توانید از روش onerror برای نمایش پیغام خطا در صورت وجود هر گونه مشکل در بارگذاری تصویر استفاده کنید، همان‌طور که در زیر نشان داده شده است.


<img src="myimage.gif" onerror="alert('An error occurred loading the image.')" />

شما می‌توانید با استفاده از رویداد onerror با بسیاری از تگ‌های HTML، پیام‌های مناسب را در صورت وجود خطاها نمایش دهید.