Difference between revisions of "Language Reference/Terms/Try-catch-finally"

From wiki.visual-prolog.com
m (1 revision(s))
(update)
Line 1: Line 1:
The try-catch-finally statement provides a way to handle possible errors that may occur in a given block of code.
The try-catch-finally statement provides means for dealing with exceptions that may occur in a given block of code.


<vipbnf><TryCatchTerm>:
<vipbnf><TryCatchTerm>:
Line 11: Line 11:
     <Term></vipbnf>
     <Term></vipbnf>


The following two terms are equivalent:
A try-construction thus have a <vpbnf>Term</vpbnf> and a list of catch and finally handlers.
 
The <vpbnf><Term></vpbnf> and the handlers are not allowed to leave backtrack points (i.e. they cannot have mode <vp>multi</vp> or <vp>nondeterm</vp>).
 
A try-construction with more than one handler is equivivalent to nesting several try-constructions with one handler each. I.e. the following term:
 
<vipbnf>try
<vipbnf>try
   <Body>
   <Body>
catch <Var> do
catch <Var1> do
   <Handler1>
   <Handler1>
finally
finally
   <Handler2>
   <Handler2>
catch <Var2> do
    <Handler3>
end try</vipbnf>
end try</vipbnf>
Is equivalent to these nested terms:


<vipbnf>try
<vipbnf>try
  try
    try
      <Body>
        try
  catch <Var> do
            <Body>
      <Handler1>
        catch <Var1> do
  end try
            <Handler1>
finally
        end try
  <Handler2>
    finally
        <Handler2>
    end try
catch <Var2> do
    <Handler3>
end try</vipbnf>
 
==== try-catch ====
 
Consider the try-catch construction
 
<vipbnf>try
    <Body>
catch <Var> do
    <Handler>
end try</vipbnf>
end try</vipbnf>
First <vpbnf><Body></vpbnf> is evaluated.
If <vpbnf><Body></vpbnf> fails or succeds the whole try construction fails or succeeds, respectively.  I.e. if <vpbnf><Body></vpbnf> does not terminate with an exception the try construction correcponds to evaluating <vpbnf><Body></vpbnf>.
If <vpbnf><Body></vpbnf> terminates with an exception, then the exception is caught by the catch handler.  Meaning that first <vpbnf><Var></vpbnf> is bound to the exception (in PFC context the exception will be a <vp>traceId</vp>) and then <vpbnf><Handler></vpbnf> is evaluated.  In this case the construction behaves as if <vpbnf><Handler></vpbnf> is evaluated with <vpbnf><Var></vpbnf> bound to the caught exception.
Notice, that no bindings are made by <vpbnf><Body></vpbnf> if it terminates with an exception.
'''Example'''  Handle the situation where a file cannot be read:
<vip>clauses
    read(Filename) = Contents :-
        try
            Contents = file::readFile(Filename)
        catch TraceId do
            stdio::writef("Could not read the file: %\n", Filename),
            exceptionDump::dumpToStdio(TraceId),
            Contents = ""
        end try.</vip>
First <vp>Contents = file::readFile(Filename)</vp> is evaluated, if that does not terminate with an exception <vp>read</vp> returns the contents of the file.
If it raises an exception the handler is evaluated with <vp>TraceId</vp> bound to the exception.  So in this case a message is written to <vp>stdio</vp> and then the exception is dumped to <vp>stdio</vp>, and finally <vp>Contents</vp> is set to the empty string which is returned as result.
==== try-finally ====

Revision as of 14:46, 20 October 2008

The try-catch-finally statement provides means for dealing with exceptions that may occur in a given block of code.

TryCatchTerm:
    try Term CatchFinally-list end try
 
CatchFinally: one of
    catch Variable do Trap-Handler
    finally Finally-Handler
 
Handler:
    Term

A try-construction thus have a Term and a list of catch and finally handlers.

The Term and the handlers are not allowed to leave backtrack points (i.e. they cannot have mode multi or nondeterm).

A try-construction with more than one handler is equivivalent to nesting several try-constructions with one handler each. I.e. the following term:

try
   Body
catch Var1 do
   Handler1
finally
   Handler2
catch Var2 do
    Handler3
end try

Is equivalent to these nested terms:

try
    try
        try
            Body
        catch Var1 do
            Handler1
        end try
    finally
        Handler2
    end try
catch Var2 do
    Handler3
end try

try-catch

Consider the try-catch construction

try
    Body
catch Var do
    Handler
end try

First Body is evaluated.

If Body fails or succeds the whole try construction fails or succeeds, respectively. I.e. if Body does not terminate with an exception the try construction correcponds to evaluating Body.

If Body terminates with an exception, then the exception is caught by the catch handler. Meaning that first Var is bound to the exception (in PFC context the exception will be a traceId) and then Handler is evaluated. In this case the construction behaves as if Handler is evaluated with Var bound to the caught exception.

Notice, that no bindings are made by Body if it terminates with an exception.

Example Handle the situation where a file cannot be read:

clauses
    read(Filename) = Contents :-
        try
            Contents = file::readFile(Filename)
        catch TraceId do
            stdio::writef("Could not read the file: %\n", Filename),
            exceptionDump::dumpToStdio(TraceId),
            Contents = ""
        end try.

First Contents = file::readFile(Filename) is evaluated, if that does not terminate with an exception read returns the contents of the file.

If it raises an exception the handler is evaluated with TraceId bound to the exception. So in this case a message is written to stdio and then the exception is dumped to stdio, and finally Contents is set to the empty string which is returned as result.

try-finally