AddErrorHandlerMethod

Applies to:uCalc Transform
Class:uCalc
Adds an error handler
Syntax
AddErrorHandler(ErrorHandlerAddress, Position)
Parameters
ErrorHandlerAddress
uCalcCallback
Address of the callback function containing the error handler code
Position
Int32
(Default = 0)
Position in which to insert the error handler
Returns
Type: Item
The error handler can later be removed using this return object
Remarks
Use this to set a a callback function that is called whenever there is an error. Your callback can do things like alert the user of the error, correct the error and resume, keep a log of errors, etc.

By default, if there are multiple error handlers, they are called starting with the most recently defined one first, ending with the first one to be defined last. In order to define a handler in a different order, specify the Position value of where it should be inserted; 0 so that it is called first, -1 so it is called last, or a positive integer indicated where it should be inserted. If the Postion value is out of bounds, it is adjusted into the maximum acceptable value.

If you set ErrorResponse to ErrorHandlerResponseEnum.ErrorResume, subsequent error handler callbacks will be bypassed and uCalc will resume operations as though no error had taken place. Note that the condition that caused the error must be corrected before resuming, otherwise uCalc may get stuck in an infinite loop.

Some functions, such as ErrorExpression, ErrorLocation, and ErrorSymbol produce a meaningful result only during the parsing stage. They do not cause other problems beyond meaningless data during the evaluation stage.

For Floating Point Environment errors, such as: Err_Float_Division_By_Zero, Err_Float_Inexact_Result, Err_Float_Invalid_Operation, Err_Float_Overflow, and Err_Float_Underflow, the uCalc error handler callbacks are called only if the corresponding environment bits are not masked.

Example 1: Adding error handlers

Sub ErrorHandlerTestCB(ByVal ucPtr As IntPtr)
   Dim ucc As New uCalc(ucPtr)
   Console.WriteLine("An error has occured!")
   Console.Write("Error #: "): Console.WriteLine(ucc.ErrorNumber())
   Console.WriteLine("Error Message: " + ucc.ErrorMessage())
   Console.WriteLine("Error Symbol: " + ucc.ErrorSymbol())
   Console.WriteLine("Error Location: " + ucc.ErrorLocation())
   Console.WriteLine("Error Expression: " + ucc.ErrorExpression())
End Sub

Sub AutoVariableDefCB(ByVal ucPtr As IntPtr)
   Dim ucc As New uCalc(ucPtr)
   if ucc.ErrorNumber() = ErrorNumberEnum.Err_Undefined_Identifier Then 
      ucc.DefineVariable(ucc.ErrorSymbol())
      ucc.ErrorResponse(ErrorHandlerResponseEnum.ErrorResume)
   End if
End Sub

Sub ErrorHandler_()' +++ example also for 2nd arg
   uc.AddErrorHandler(uc.PinAddr(AddressOf ErrorHandlerTestCB))
   uc.AddErrorHandler(uc.PinAddr(AddressOf AutoVariableDefCB))
   Console.WriteLine(uc.EvalStr("1+")) ' Returns "Syntax error"
   ' Output
   ' An error has occured!
   ' Error #: 2
   ' Error Message: Syntax error
   ' Error Symbol: +
   ' Error Location: 1
   ' Error Expression: 1+

   Console.WriteLine(uc.EvalStr("5/0")) ' Returns "Division by 0"
   ' Output
   ' An error has occured!
   ' Error #: 20
   ' Error Message: Division by 0
   ' Error Symbol: 
   ' Error Location: 0
   ' Error Expression: 

   uc.Eval("AutoTest = 123")
   Console.WriteLine(uc.Eval("AutoTest * 1000")) ' Returns 123000
End Sub

          

static void ErrorHandlerTestCB(IntPtr ucPtr) {
   uCalc ucc = New uCalc(ucPtr);
   Console.WriteLine("An error has occured!");
   Console.Write("Error #: "); Console.WriteLine(ucc.ErrorNumber());
   Console.WriteLine("Error Message: " + ucc.ErrorMessage());
   Console.WriteLine("Error Symbol: " + ucc.ErrorSymbol());
   Console.WriteLine("Error Location: " + ucc.ErrorLocation());
   Console.WriteLine("Error Expression: " + ucc.ErrorExpression());
}

static void AutoVariableDefCB(IntPtr ucPtr) {
   uCalc ucc = New uCalc(ucPtr);
   if (ucc.ErrorNumber() == ErrorNumberEnum.Err_Undefined_Identifier) {
      ucc.DefineVariable(ucc.ErrorSymbol());
      ucc.ErrorResponse(ErrorHandlerResponseEnum.ErrorResume);
   }
}

static void ErrorHandler_() { // +++ example also for 2nd arg
   uc.AddErrorHandler(uc.PinAddr(ErrorHandlerTestCB));
   uc.AddErrorHandler(uc.PinAddr(AutoVariableDefCB));
   Console.WriteLine(uc.EvalStr("1+")); // Returns "Syntax error";
   // Output
   // An error has occured!
   // Error #: 2
   // Error Message: Syntax error
   // Error Symbol: +
   // Error Location: 1
   // Error Expression: 1+
   
   Console.WriteLine(uc.EvalStr("5/0")); // Returns "Division by 0";
   // Output
   // An error has occured!
   // Error #: 20
   // Error Message: Division by 0
   // Error Symbol: 
   // Error Location: 0
   // Error Expression: 
   
   uc.Eval("AutoTest = 123");
   Console.WriteLine(uc.Eval("AutoTest * 1000")); // Returns 123000;
}

          

procedure ErrorHandlerTestCB(ucPtr: System.Pointer);
begin
   
//ucc uCalc.Create(ucPtr);;
   WriteLn('An error has occured!');
   Write('Error #: ');; WriteLn(ucc.ErrorNumber());
   WriteLn('Error Message: ' + ucc.ErrorMessage());
   WriteLn('Error Symbol: ' + ucc.ErrorSymbol());
   WriteLn('Error Location: ' + ucc.ErrorLocation());
   WriteLn('Error Expression: ' + ucc.ErrorExpression());
End;

procedure AutoVariableDefCB(ucPtr: System.Pointer);
begin
   
//ucc uCalc.Create(ucPtr);;
   if ucc.ErrorNumber() = ErrorNumberEnum.Err_Undefined_Identifier Then 
begin
   
      ucc.DefineVariable(ucc.ErrorSymbol());
      ucc.ErrorResponse(ErrorHandlerResponseEnum.ErrorResume);

End;
End;

procedure ErrorHandler_();
begin
   // +++ example also for 2nd arg
   uc.AddErrorHandler(ErrorHandlerTestCB);
   uc.AddErrorHandler(AutoVariableDefCB);
   WriteLn(uc.EvalStr('1+')); // Returns 'Syntax error';
   // Output
// An error has occured!
// Error #: 2
// Error Message: Syntax error
// Error Symbol: +
// Error Location: 1
// Error Expression: 1+

   WriteLn(uc.EvalStr('5/0')); // Returns 'Division by 0';
   // Output
// An error has occured!
// Error #: 20
// Error Message: Division by 0
// Error Symbol: 
// Error Location: 0
// Error Expression: 

   uc.Eval('AutoTest = 123');
   WriteLn(uc.Eval('AutoTest * 1000')); // Returns 123000;
End;

          

void _stdcall ErrorHandlerTestCB(uCalcPtr ucPtr) {
   uCalc ucc(ucPtr);
   cout << "An error has occured!" << endl;
   cout << "Error #: "; cout << ucc.ErrorNumber() << endl;
   cout << "Error Message: " << ucc.ErrorMessage() << endl;
   cout << "Error Symbol: " << ucc.ErrorSymbol() << endl;
   cout << "Error Location: " << ucc.ErrorLocation() << endl;
   cout << "Error Expression: " << ucc.ErrorExpression() << endl;
}

void _stdcall AutoVariableDefCB(uCalcPtr ucPtr) {
   uCalc ucc(ucPtr);
   if (ucc.ErrorNumber() == ErrorNumberEnum::Err_Undefined_Identifier) {
      ucc.DefineVariable(ucc.ErrorSymbol());
      ucc.ErrorResponse(ErrorHandlerResponseEnum::ErrorResume);
   }
}

void ErrorHandler_() { // +++ example also for 2nd arg
   uc.AddErrorHandler(ErrorHandlerTestCB);
   uc.AddErrorHandler(AutoVariableDefCB);
   cout << uc.EvalStr("1+") << endl; // Returns "Syntax error";
   // Output
   // An error has occured!
   // Error #: 2
   // Error Message: Syntax error
   // Error Symbol: +
   // Error Location: 1
   // Error Expression: 1+
   
   cout << uc.EvalStr("5/0") << endl; // Returns "Division by 0";
   // Output
   // An error has occured!
   // Error #: 20
   // Error Message: Division by 0
   // Error Symbol: 
   // Error Location: 0
   // Error Expression: 
   
   uc.Eval("AutoTest = 123");
   cout << uc.Eval("AutoTest * 1000") << endl; // Returns 123000;
}

          

static void ErrorHandlerTestCB(uCalcPtr ucPtr) {
   uCalc ucc(ucPtr);
   Console::WriteLine("An error has occured!");
   Console::Write("Error #: "); Console::WriteLine(ucc.ErrorNumber());
   Console::WriteLine("Error Message: " + ucc.ErrorMessage());
   Console::WriteLine("Error Symbol: " + ucc.ErrorSymbol());
   Console::WriteLine("Error Location: " + ucc.ErrorLocation());
   Console::WriteLine("Error Expression: " + ucc.ErrorExpression());
}

static void AutoVariableDefCB(uCalcPtr ucPtr) {
   uCalc ucc(ucPtr);
   if (ucc.ErrorNumber() == ErrorNumberEnum::Err_Undefined_Identifier) {
      ucc.DefineVariable(ucc.ErrorSymbol());
      ucc.ErrorResponse(ErrorHandlerResponseEnum::ErrorResume);
   }
}

static void ErrorHandler_() { // +++ example also for 2nd arg
   uc.AddErrorHandler(ucPinAddr(ErrorHandlerTestCB));
   uc.AddErrorHandler(ucPinAddr(AutoVariableDefCB));
   Console::WriteLine(uc.EvalStr("1+")); // Returns "Syntax error";
   // Output
   // An error has occured!
   // Error #: 2
   // Error Message: Syntax error
   // Error Symbol: +
   // Error Location: 1
   // Error Expression: 1+
   
   Console::WriteLine(uc.EvalStr("5/0")); // Returns "Division by 0";
   // Output
   // An error has occured!
   // Error #: 20
   // Error Message: Division by 0
   // Error Symbol: 
   // Error Location: 0
   // Error Expression: 
   
   uc.Eval("AutoTest = 123");
   Console::WriteLine(uc.Eval("AutoTest * 1000")); // Returns 123000;
}

          
DLL import code
<DllImport(uCalcDLL, CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Cdecl, EntryPoint:="AddErrorHandler")> _

Private Function AddErrorHandler__(ByVal uCalcHandle As IntPtr,ByVal ErrorHandlerAddress As uCalcDelegate , ByVal Position As Int32  ) As IntPtr
End Function
            
[DllImport(uCalcDLL, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl, EntryPoint="AddErrorHandler")]

protected static extern IntPtr AddErrorHandler_(IntPtr uCalcHandle,uCalcDelegate ErrorHandlerAddress ,  Int32 Position  );
            
{DLLImport}function AddErrorHandler__(uCalcHandle: System.Pointer;ErrorHandlerAddress: System.Pointer ; Position: Int32): System.Pointer; cdecl; external uCalcDLL name 'AddErrorHandler';

            
typedef uCalcPtr (* __AddErrorHandler)(void *uCalcHandle, UCCALLBACK ErrorHandlerAddress ,  int32_t Position  ); 

            
[DllImport(uCalcLib, CharSet=CharSet::Ansi, CallingConvention=CallingConvention::Cdecl, EntryPoint = "AddErrorHandler")]

static uCalcPtr AddErrorHandler_(void *  uCalcHandle, UCCALLBACK ErrorHandlerAddress ,  Int32 Position);
            
See also
Prev | Next