PDA

View Full Version : Handling Errors and Exceptions in Delphi



m-khorsandi
یک شنبه 15 بهمن 1385, 08:06 صبح
Error و Exception :

هر Exception یی معمولاً یک وضعیت خطاست یا اتفاقی ست که جریان اجرای طبیعی برنامه را متوقف می‌کند . هر وقت که حاصل پردازش یک خط از کد ، خطایی باشد ، دلفی شیئی می‌سازد که از کلاس TObject مشتق شده و خطا را توسط آن به نمایش در می‌آورد.

Guarded Block
هر برنامه یا بوسیله بعضی کدهای خاتمه دهنده ی برنامه یا بوسیله کنترل خطاها ، گاهاً هر دو ، نسبت به خطاها واکنش نشان می‌دهد. راهی برای به دام انداختن error یا exception روی کدهای مشخص وجود دارد و این زمانیست که بتوانید حدس بزنید در بخشی از کد ، ممکن ست error یا exception یی رخ دهد. Try..Except ،دستورات را در بلوکی حفاظت شده اجرا می‌کند.

شکل کلی :

try
{guarded block of code}
except
on <ESomeException> do begin
{exception block-handles SomeException}
end;
end;

اگر دستورات نوشته شده در بخش try بدون بروز هیچگونه exception یی اجرا شوند، از اجرای قسمت except صرف نظر می‌شود و کنترل برنامه به بعد از کلمه کلیدی end منتقل می‌شود. بنابراین ما دستوراتی که ممکن ست اجرای آنها باعث بوجود آمدن خطایی شود را در بخش try (یعنی بین کلمه try و except) و دستوراتی که بعد از بروز خطا میبایست اجرا شوند را در بخش except (یعنی بین کلمه except و end) می‌نویسیم، به این قسمت اصطلاحاً exception handling یا کنترل کننده خطا اطلاق می‌شود.

مثال :


...
Zero:=0;
try
dummy:= 10 / Zero;
except
on EZeroDivide do
MessageDlg('Can not divide by zero!',
mtError, [mbOK], 0) ;
end;
...


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


...
Zero:=0;
try
dummy:= 10 / Zero;
except
MessageDlg('error !', mtError, [mbOK], 0) ;
end;
...


Protecting Resources – محافظت از منابع :
وقتی که بخشی از کد ،resource یی را در اختیار می‌گیرد ، اغلب لازم ست که از آزاد شدن آن resource مطمئن شد ، بدون توجه به اینکه اون بخش از کد ، طبیعی خاتمه پیدا کند یا با خطا. در این حالت می‌توان از try..finally استفاده کرد. در واقع try..finally ،نوعی بلوک محافظ حافظه ست و می‌تواند از بوجود آمدن Memory Leak جلوگیری کند و از این نظر کد مطمئنی خواهید داشت.

شکل کلی :


{some code to allocate resources}
try
{guarded block of code}
finally
{termination block - code to free resources}
end;


نحوه ی اجرا به این صورت ست که دستورات مابین کلمات کلیدی try و finally اجرا می‌شوند و اگر خطایی اتفاق افتاد یا هیچ خطایی اتفاق نیفتاد ، دستورات مابین کلمات کلیدی finally و end اجرا می‌شوند، یعنی در هر صورت قسمت finally اجرا می‌شود.

مثال :


...
AboutBox:=TAboutBox.Create(nil) ;
try
AboutBox.ShowModal;
finally
AboutBox.Release;
end;
...


Application.OnException
اگر شما خطاهایی که ممکن ست در یک برنامه اتفاق بیفتد را کنترل نکنید ، دلفی از کنترل کننده ی خطای پیش فرض خود استفاده خواهد کرد، که نتیجه آن نمایش دادن یک message box هست. همچنین می‌توانید از رویداد Application.Exception استفاده کنید و کنترل خطا را در سطح Application بنویسید ، به این معنی که نیازی نیست برای هر مجموعه از دستورات (که احتمال خطای آن وجود دارد) ، از try..except استفاده کنید و فقط و فقط کنترل کننده خطا را در این رویداد می‌نویسید و از این پس با بروز هر error یا exception یی این رویداد به صورت خودکار فراخوانی می‌شود.

Break On Exceptions – وقفه روی exception ها
وقتی برای قسمتهایی از برنامه ، کنترل کننده خطا (exception handling)می‌نویسید ، احتمالاً نمی‌خواهید هنگام بروز یک خطا (که کنترل کننده ی آن را هم نوشته اید) ، برنامه متوقف شود و دلفی، سورس برنامه را به همراه یک پیغام خطای زیبا! نمایش دهد، حداقل در زمان تست کنترل کننده خطا، چون قصد دارید نتیجه کنترل کننده‌ای را که نوشته‌اید ، ببینید. ویژگی بزرگی در دلفی وجود دارد که این کار را برایتان انجام می‌دهد ، یعنی می‌توانید نمایش پیغام خطا را توسط دلفی (که می‌تواند هنگام تست کنترل کننده خطایی که نوشتید آزار دهنده باشد) غیر فعال کنید.



Tools -> Debugger Options -> Language Exceptions Tab -> Stop on Delphi Exceptions

anubis_ir
یک شنبه 15 بهمن 1385, 09:56 صبح
این ابزار هم در اینباره بسیار مفید است
http://www.madshi.net/

همچنین
http://www.eurekalog.com/

مجتبی جوادی
سه شنبه 23 مرداد 1386, 21:41 عصر
آقای خرسندی ممنون از لطف شما
ولی می خواهم بیشتر درباره نیازم به شما توضیح دهم .
من یک کامپوننت دانلو کرده ام که این کامپوننت کاملا جواب گوی مشکلات من می باشد و دقیقاً آنچه که می خواهم را بدست آوردم . ولی یک مشکل دیگری وجود دارد و آن اینکه هربار که این کامپوننت مورد استفاده قرار می گیرد پیغام می دهد که باید رجیستر شود اما کاملا کار می کند . حال می خواهم قبل از اجرا پیغام خطای آن که با یک ok برطرف می شود ، حذف کنم . آیا این عمل امکان دارد .
با تشکر

Mohammad_Mnt
سه شنبه 23 مرداد 1386, 23:44 عصر
قبل از لود کردن کامپوننت، کد کیلد Enter که 13 است را بفرست توی بافر صفحه‌کلید.

مجتبی جوادی
چهارشنبه 24 مرداد 1386, 15:49 عصر
میشه بیشتر توضیح بدید . یا اینکه لطف کند بگویید که چگونه باید بنویسم
ممنون

mohammad-j
پنج شنبه 01 آذر 1386, 16:39 عصر
سعی شود حتما از این تکنیک در برنامه ها استفاده شود
موفق باشید

matinebi
چهارشنبه 06 آذر 1387, 08:43 صبح
اگه بتونیم برای کنترل کامل خطا در برنامه فایل متنی با نام log.txt ایجاد کنیم که تمام خطا های برنامه در این فایل متنی قرار گیرد تا در صورت ایجاد مشکل در برنامه دیگه مجبور نباشیم کل سرس برنامه رو دونبال خطا بگردیم خیلی بهتره

vcldeveloper
چهارشنبه 06 آذر 1387, 10:15 صبح
اگه بتونیم برای کنترل کامل خطا در برنامه فایل متنی با نام log.txt ایجاد کنیم که تمام خطا های برنامه در این فایل متنی قرار گیرد تا در صورت ایجاد مشکل در برنامه دیگه مجبور نباشیم کل سرس برنامه رو دونبال خطا بگردیم خیلی بهتره
از چی بهتره؟ استفاده از Exception Handling اصلی هست که همه باید رعایت کنند. حالا اگر یکی می خواد در کنارش خطاها را هم Log کنه، مسئله ایی نیست، و میتونه در ساده ترین حالت، برای Application.OnException کدی بنویسه که همه Exceptionها را Log کنه، ولی Log کردن Exceptionها جایگزین Exception Handling نمیشه.

Naruto
جمعه 22 آذر 1387, 06:27 صبح
سلام .
RaiseEvent در مورد Application.OnException چطور انجام میشه؟
یعنی کجا ازش استفاده کنیم تا هر زمان که خطایی نامعلوم رخ داد پیغام بده.
اگر Exception Handling در کل برنامه ثابت باشه آیا برای هر رویداد دلخواه یه Application.OnException مجزا نیاز هست؟
با تشکر.