سیستم خطای Factor سه بخش دارد: throw برای اعلام یک خطا،
recover برای رسیدگی به یکی، و ERROR: برای تعریف نوع خطای
خودتان.
throwthrow (در kernel) یک خطا ایجاد میکند. آرگومان میتواند
هر مقداری باشد (یک رشته، یک عدد، یا یک «تاپل») و همان خطایی
میشود که بعداً میتوانید بررسی کنید:
! DOCTEST: SKIP
"file not found" throw
throw برنمیگردد؛ بقیهی «واژه»ی جاری نادیده گرفته میشود.
recoverrecover (در continuations) معادل try/catch در
Factor است. یک «quotation» try و یک quotation recovery میگیرد:
recover ( try recovery -- )
اگر try بدون پرتاب خطا تمام شود، recovery نادیده گرفته
میشود. اگر try خطا پرتاب کند، خطا روی «پشته» قرار میگیرد و
recovery اجرا میشود:
[ "boom" throw ] [ drop "caught" ] recover .
! => "caught"
[ "ok" ] [ drop "never runs" ] recover .
! => "ok"
when از kernel همراه طبیعی آن است: یک quotation را
تنها زمانی اجرا میکند که بالای پشته مقداری باشد که درست ارزیابی
میشود:
: check-positive ( n -- )
0 < [ "negative!" throw ] when ;
ERROR:ERROR: یک کلاس تاپل و یک واژه تعریف میکند که یک «نمونه»ی
تازه میسازد و آن را پرتاب میکند:
! DOCTEST: SKIP
ERROR: not-found path ;
"/missing" not-found
! throws T{ not-found { path "/missing" } }
یک خطای بدون «شکاف» فقط ERROR: name ; است؛ فراخوانی name یک
نمونهی خالی پرتاب میکند. تاپلهایی که با ERROR: تعریف میشوند
یک «محمول» کلاس name? دارند که میتوانید از آن برای آزمودن
اینکه آیا خطای گرفتهشده از آن نوع بوده است استفاده کنید.
یک خطای گرفتهشده فقط یک تاپل است، بنابراین هر شکاف ERROR: همان
«خواننده»ی slot>> خودکار را دارد که هر تاپل دیگری دارد.
! DOCTEST: SKIP
{
T{ not-found { path "/a" } }
T{ not-found { path "/b" } }
}
[ path>> ] map . ! => { "/a" "/b" }
النا، مدیر کیفیت جدید کارخانهی روزنامه، از شما میخواهد نرمافزار کوچکی بنویسید که سالن تولید را پایش کند.
با استفاده از واژهی تجزیهی ERROR: یک کلاس چندتایی خطا به اسم machine-error تعریف کنید. به هیچ اسلاتی نیاز ندارد.
machine-error ! throws a fresh machine-error
check-humidity را تعریف کنید. این واژه یک مقدار رطوبت را از پشته برمیدارد و وقتی این مقدار اکیداً بزرگتر از 70 باشد، رشتهی "humidity too high" را throw میکند. در غیر این صورت، هیچ مقداری برنمیگرداند.
50 check-humidity ! returns nothing
80 check-humidity ! throws "humidity too high"
check-temperature را تعریف کنید. این واژه یک مقدار دما را از پشته برمیدارد و وقتی این مقدار اکیداً بزرگتر از 500 باشد، رشتهی "temperature too high" را throw میکند. در غیر این صورت، هیچ مقداری برنمیگرداند.
400 check-temperature ! returns nothing
600 check-temperature ! throws "temperature too high"
monitor را طوری تعریف کنید که یک مقدار رطوبت و یک مقدار دما را از پشته بردارد و هر دو بررسی را اجرا کند. اگر هر یک از این بررسیها throw کند، monitor باید در عوض یک machine-error تازه throw کند. اگر هر دو با موفقیت بگذرند، monitor هیچ مقداری برنمیگرداند.
50 400 monitor ! returns nothing
80 400 monitor ! throws a machine-error
50 600 monitor ! throws a machine-error
monitor-batch را طوری تعریف کنید که آرایهای از خوانشهای { humidity temperature } را بگیرد و برگرداند که چند مورد از آنها شکست میخورند (یعنی چند مورد باعث میشوند که monitor خطا throw کند).
{ { 50 400 } { 80 400 } { 50 600 } { 60 200 } } monitor-batch .
! => 2