| 
 What is an exception?  
An exception is simply a signal that something has gone wrong. Under object pascal all exceptions are represented by an exception object, which contains information about the error that has occurred. The most basic exception object simply contains a text string called message, which contains a string representation of the error that occurred.  
The exception object is an object like everything else. It is normal to create your own exception objects if your error needs more information than just a string. 
  
Handling errors in Smart Mobile Studio  
Whilst we all want to spend our time writing functional code, errors will and do occur in in code from time to time.  
In serious code you should handle error situations so that at the very least, the user is informed about the error in your chosen way. 
Pas2JS uses the event handling approach to error handling. Errors are (mostly) treated as exceptions, which cause program operation to suspend and jump to the nearest exception handler. If you don't have one, this will be the Pas2JS default handler - it will report the error and terminate your program. 
Often, you will want to handle the error, and continue with your program. For example, you may be trying to display a picture on a page, but cannot find it. So you might display a placeholder instead.  
  
NOTES: 
Except: Starts the error trapping clause of a Try statement.  
Finally: Starts the unconditional code section of a Try statement.  
On: Defines exception handling in a Try Except clause. 
Try: Starts code that has error trapping. 
  
  
TRY, EXCEPT where there are problems  
  
Pas2JS provides a simply construct for wrapping code with exception handling. When an exception occurs in the wrapped code (or anything it calls), the code will jump to the exception handling part of the wrapping code: 
  
begin 
Try 
  // The code we want to execute 
Except 
  // This code gets executed if an exception occurs in the above block 
end; 
end; 
 | 
 
 
 
  
The Except keyword is used to mark the start of a block of statements that handle an exception in a Try clause. If the Except block can handle the exception, then the program is not terminated.  
We literally try to execute some code, which will run except when an error (exception) occurs. Then the except code will take over.  
  
EXCEPT using Delphi:  
| · | Version 1  
In this version, if the Try clause generates an exception the Except clause is executed. This is used to take alternative action when something unexpected goes wrong. The except clause cannot determine the error type however. When the division fails, the code jumps to the except block. The first ShowMessage statement therefore does not get executed. |  
 | · | Version 2  
This is similar to version 1, but specifies different actions for different exception types, such as EInOutError. An Else clause can be used as a catch all for unexpected exception types. The general exception type Exception can be used to catch all exception types.  
  
By assigning a Name to the exception, the message text of the exception (Name.Message) can be obtained for display or other uses.  
  
When an exception is raised in a version 2 setup, if the exception is not acted upon by On or Else statements, then a check is made to see if we are in a nested Try block. If so, the Except clause of this parent Try is processed. If no On or Else clause is found, the program terminates.  
  
The Else clause is not really necessary - it is better to use On E:Exception Do, the generic exception handling, since it still provides the error message (E.Message). |  
   
  
Catching exceptions with Smart Mobile Studio 
  
Catching an exception is done inside a try / except block. If the code inside the block raises an exception then you can safely handle it before either exiting your method or continuing execution. 
  
EXCEPT with Smart Mobile Studio  
 Please include the units SmartCL.System and System.Complex to use Exceptions. Differently from Delphi, Pas2JS does not trap the error automatically. You have, firstly, check if a variable have unexpected type and then start the error trapping in the except block, which you can handle the exception.  Here is how you raise an exception: 
  
 if (something <> what_you_expect) then 
     raise exception.create('I expected something else'); 
  
 | 
 
 
 
  
Example code : Zero divide with a plain Except block in Pas2JS 
procedure TForm1.btnClearClick(Sender: TObject); 
var 
  number, zero : Integer; 
begin 
  // Try to divide an integer by zero - to raise an exception 
  Try 
    zero   := 0; 
    number := 1 div zero; 
  
    if IsInfinite(number) then raise Exception.Create('Division by zero') else 
    ShowMessage('number / zero = '+FloatToStr(number)); 
   
  Except 
    ShowMessage('Unknown error encountered'); 
  end; 
end; 
 | 
 
 
 
Result is: Unknown error encountered 
  
function btnClearClick(Self, Sender$4) { 
      var number = 0; 
      var zero = 0; 
      try { 
         zero = 0; 
         number = $Div(1,zero); 
         if (IsInfinite(number)) { 
            throw Exception.Create($New(Exception),"Division by zero"); 
         } else { 
            alert("number / zero = "+((number)).toString()); 
         } 
      } catch ($e) { 
         alert("Unknown error encountered")      } 
   } 
 | 
 
 
 
  
  
Example code : Example code : Divide by zero with an Except On clause 
procedure TForm1.W3Button1Click(Sender: TObject); 
var 
  number, zero : Integer; 
begin 
  // Try to divide an integer by zero - to raise an exception 
  Try 
    zero   := 0; 
    number := 1 div zero; 
    if IsInfinite(number) then raise Exception.Create('Division by zero') else 
    ShowMessage('number / zero = '+IntToStr(number)); 
  Except 
    on E : Exception do 
     Begin 
       ShowMessage(E.ClassName+' error raised, with message : '+E.Message); 
     end; 
  end; 
end; 
 | 
 
 
 
Result is: It will show a message Exception error raised with message : Division by zero 
  
Important : you can determine the type of error that occured by using the generic exception handling - On E:Exception Do. E is a pointer to the exception object that is created by the exception condition. E.ClassName gives the exception type, such as 'EDivByZero', as shown in the final example code. 
  
function W3Button1Click(Self, Sender$6) { 
      var number$1 = 0; 
      var zero$1 = 0; 
      try { 
         zero$1 = 0; 
         number$1 = $Div(1,zero$1); 
         if (IsInfinite(number$1)) { 
            throw Exception.Create($New(Exception),"Division by zero"); 
         } else { 
            alert("number / zero = "+number$1.toString()); 
         } 
      } catch ($e) { 
         var E = $W($e); 
         alert(TObject.ClassName($Check(E,"").ClassType)+" error raised, with message : "+ 
                                                           $Check(E,"").FMessage)      } 
   } 
 | 
 
 
 
  
  
Being more selective 
  
While catching all types of exception with the same error handler is very effective, there are times when you want to handle specific errors differently. Object Pascal allows you to handle that in the following way: 
  
Example code : Custom Exception 
EAbort = class(Exception); 
  
  
{ Raise abort exception } 
procedure DoSomething; 
begin 
  raise EAbort.Create('Abort without dialog'); 
end; 
  
  
procedure TForm1.W3Button4Click(Sender: TObject); 
var 
  number, zero: Integer; 
begin 
  // Raise an selection exception 
  try 
    zero := 1; 
    number := 0 div zero; 
  
    if number = 0 then 
      DoSomething; 
  
    if IsInfinite(number) then 
      raise Exception.Create('Division by zero') 
    else 
    begin 
      ShowMessage('number / zero = ' + FloatToStr(number)); 
  
    end; 
  except 
    on e: EAbort do 
      ShowMessage('A different error occured: ' + e.message); 
  
    on e: exception do 
      ShowMessage('All other errors are handled by this one: ' + e.message); 
  end; 
end; 
 | 
 
 
 
Result is: It will show a message A different error occured: Abort without dialog 
  
function W3Button4Click(Self, Sender$9) { 
      var number$4 = 0; 
      var zero$4 = 0; 
      try { 
         zero$4 = 1; 
         number$4 = $Div(0,zero$4); 
         if (!number$4) { 
            DoSomething(); 
         } 
         if (IsInfinite(number$4)) { 
            throw Exception.Create($New(Exception),"Division by zero"); 
         } else { 
            alert("number / zero = "+((number$4)).toString()); 
         } 
      } catch ($e) { 
         if ($Is($e,EAbort)) { 
            var e$11 = $W($e); 
            alert("A different error occured: "+$Check(e$11,"").FMessage)} 
         else if ($Is($e,Exception)) { 
            var e$12 = $W($e); 
            alert("All other errors are handled by this one: "+$Check(e$12,"").FMessage)} 
         else throw $e 
      } 
   } 
 | 
 
 
 
  
  
Ignoring exceptions 
  
Unless you handle an exception it causes the execution of the current procedure (recursively back to the first caller) to be aborted. In other words, it will stop running your code and propagate the error upwards. So if you don’t handle errors, it will report it to the method that called your code, or exit that and continue until it finds an exception handler. If you simply want to ignore any errors and continue no matter what (not recommended) you can do as such: 
  
Example code : Divide by zero with no message error 
procedure TForm1.W3Button1Click(Sender: TObject); 
var 
  number, zero : Integer; 
begin 
  // Try to divide an integer by zero - to raise an exception 
  Try 
    zero   := 0; 
    number := 1 div zero; 
    if IsInfinite(number) then raise Exception.Create('Division by zero') else 
    ShowMessage('number / zero = '+IntToStr(number)); 
  Except 
    on E : Exception do; // Ignore any error and continue 
  end; 
end; 
 | 
 
 
 
Result is: neither messages nor console error 
  
function W3Button1Click(Self, Sender$6) { 
      var number$1 = 0; 
      var zero$1 = 0; 
      try { 
         zero$1 = 0; 
         number$1 = $Div(1,zero$1); 
         if (IsInfinite(number$1)) { 
            throw Exception.Create($New(Exception),"Division by zero"); 
         } else { 
            alert("number / zero = "+number$1.toString()); 
         } 
      } catch ($e) { 
         var E = $W($e); 
         /* null */ 
      } 
   } 
 | 
 
 
 
  
  
And FINALLY ...  
  
Suppose that instead of trapping the error where it occurs, you may want to let a higher level exception handler in your code to do a more global trapping. Delphi provides an alternative part to the exception wrapper the Finally clause. Instead of being called when an exception occurs, the finally clause is always called after part or all of the try clause is executed. However, it does not trap the error - the next highest exception handling (try) block that we are nested in is located and executed. 
  
Example code : Zero divide with a finally clause 
procedure TForm1.W3Button3Click(Sender: TObject); 
var 
  number, zero : Integer; 
begin 
  // Try to divide an integer by zero - to raise an exception 
  Try 
    zero   := 0; 
    number := 1 div zero; 
    if IsInfinite(number) then raise Exception.Create('Division by zero') else 
    ShowMessage('number / zero = '+IntToStr(number)); 
  Finally 
    if number = -1 then 
    begin 
      ShowMessage('Number was not assigned a value - using default'); 
      number := 0; 
    end; 
  end; 
end; 
 | 
 
 
 
Result is:  
  Number was not assigned a value - using default 
  Then, the program terminates with an Uncaught #<Object> console message - the finally clause did not trap the error. 
   
  
function W3Button3Click(Self, Sender$8) { 
      var number$3 = 0; 
      var zero$3 = 0; 
      try { 
         zero$3 = 0; 
         number$3 = $Div(1,zero$3); 
         if (IsInfinite(number$3)) { 
            throw Exception.Create($New(Exception),"Division by zero"); 
         } else { 
            alert("number / zero = "+number$3.toString()); 
         } 
      } finally { 
         if (number$3==(-1)) { 
            alert("Number was not assigned a value - using default"); 
            number$3 = 0; 
         } 
      } 
   } 
 | 
 
 
 
  
  
Example code : Zero divide with a finally clause and Except 
procedure TForm1.W3Button2Click(Sender: TObject); 
var 
  number, zero: Integer; 
begin 
  // Try to divide an integer by zero - to raise an exception 
  try 
    try 
      zero := 0; 
      number := 1 div zero; 
      if IsInfinite(number) then raise Exception.Create('Division by zero') 
      else 
        ShowMessage('number / zero = ' + IntToStr(number)); 
    except 
      number := -1; 
    end; 
  finally 
    if number = -1 then 
    begin 
      ShowMessage('Number was not assigned a value - using default'); 
      number := 0; 
    end; 
  end; 
  WriteLn('number is: '+IntToStr(number)); 
end; 
 | 
 
 
 
Result is:  
  Number was not assigned a value - using default 
  Then, the program display console message number is 0. The program trap the error and set number to -1 
  
  
function W3Button2Click(Self, Sender$7) { 
      var number$2 = 0; 
      var zero$2 = 0; 
      try { 
         try { 
            zero$2 = 0; 
            number$2 = $Div(1,zero$2); 
            if (IsInfinite(number$2)) { 
               throw Exception.Create($New(Exception),"Division by zero"); 
            } else { 
               alert("number / zero = "+number$2.toString()); 
            } 
         } catch ($e) { 
            number$2 = -1; 
         } 
      } finally { 
         if (number$2==(-1)) { 
            alert("Number was not assigned a value - using default"); 
            number$2 = 0; 
         } 
      } 
      WriteLn(("number is: "+number$2.toString())); 
   } 
 | 
 
 
 
  
  
Try-Finally is normally used by a routine to allow cleanup processing to take place, such as freeing resources, with the exception being correctly passed to the caller to handle. In this example, a exception is trapped. 
  
  
 |