uCalc API Version: 2.1.3-preview.2 Released: 6/16/2026

Warning

uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.

AddHandler

Method

Product: 

Fast Math Parser

Class: 

ErrorInfo

Registers a callback function to intercept, log, or resolve errors during parsing and evaluation.

Syntax

AddHandler(DELEGATE_UCALC, int)

Parameters

callback
DELEGATE_UCALC
The address of the user-defined callback function.
priority
int
(Default = 0)
The insertion priority.

Return

Item

Item representing the error handler

Remarks

AddErrorHandler lets you attach a custom function that can intercept and respond to errors (such as a syntax error, unknown symbol, or divide-by-zero) raised during parsing or evaluation. This allows for centralized error management, logging, or "soft" failure modes where the application can continue running despite invalid input. Error handlers can:

  • Display or log error information
  • Modify the error response
  • Attempt recovery and resume execution
  • Abort evaluation early
  • Provide custom debugging or diagnostic output

Handlers are invoked in a stack‑like order unless you specify a custom insertion position.


Handler Ordering

By default, handlers are called:

  1. Most recently added handler first
  2. Then older handlers in reverse order of registration

You can override this by specifying the priority parameter:

  • 0 (default): Insert at the front of the queue (called first)
  • -1: Insert at the end (called last)
  • Positive integer: Insert at that index
  • Out‑of‑range values are automatically clamped to valid bounds

This allows you to build layered error‑handling strategies (e.g., a global logger at the end, a temporary handler at the front).


Resuming After an Error

By default (ErrorHandlerResponse::Abort), an error stops the parsing or evaluation process. As a result, Error.Code will return a value other than ErrorCode::None, and ErrorMessage() will return a non-empty string. EvalStr() or EvaluateStr() would also return an error message.

However, inside your callback, you can change the outcome using uc.ErrorResponse(...).

If you set:

uCalc.ErrorResponse(ErrorHandlerResponse::Resume)

…then:

  • The current handler runs
  • All subsequent handlers are skipped
  • uCalc resumes execution as if no error occurred

⚠️ Important:
You must correct the condition that caused the error before resuming.
Otherwise, uCalc may repeatedly encounter the same error and enter an infinite loop.


Parsing‑Stage vs Evaluation‑Stage Error Information

Some error‑inspection functions only produce meaningful results during the parsing stage:

  • uCalc.ErrorExpression()
  • uCalc.ErrorLocation()
  • uCalc.ErrorSymbol()

During evaluation, these functions still work safely but return:

  • ErrorLocation0
  • ErrorExpression → empty string
  • ErrorSymbol → empty string

This distinction helps you determine whether the error occurred during parsing or evaluation.


Return Value

AddErrorHandler returns an Item representing the handler.
You can later remove the handler by calling .Release() on this returned object.

Examples

Adding an error handler callback
				
					using uCalcSoftware;

var uc = new uCalc();

static void MyErrorHandler(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine("An error has occurred!");
   Console.WriteLine($"Error #: {(int)uc.Error.Code}");
   Console.WriteLine($"Error Message: {uc.Error.Message}");
   Console.WriteLine($"Error Symbol: {uc.Error.Symbol}");
   Console.WriteLine($"Error Location: {uc.Error.Location}");
   Console.WriteLine($"Error Expression: {uc.Error.Expression}");
}


uc.Error.AddHandler(MyErrorHandler);
Console.WriteLine(uc.EvalStr("123+"));
Console.WriteLine("");

uc.Error.TrapOnDivideByZero = true;
Console.WriteLine(uc.EvalStr("5/0"));
				
			
An error has occurred!
Error #: 257
Error Message: Syntax error
Error Symbol: +
Error Location: 3
Error Expression: 123+
Syntax error

An error has occurred!
Error #: 8
Error Message: Division by 0
Error Symbol: 
Error Location: 0
Error Expression: 
Division by 0
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call MyErrorHandler(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "An error has occurred!" << endl;
   cout << "Error #: " << (int)uc.Error().Code() << endl;
   cout << "Error Message: " << uc.Error().Message() << endl;
   cout << "Error Symbol: " << uc.Error().Symbol() << endl;
   cout << "Error Location: " << uc.Error().Location() << endl;
   cout << "Error Expression: " << uc.Error().Expression() << endl;
}

int main() {
   uCalc uc;
   uc.Error().AddHandler(MyErrorHandler);
   cout << uc.EvalStr("123+") << endl;
   cout << "" << endl;

   uc.Error().TrapOnDivideByZero(true);
   cout << uc.EvalStr("5/0") << endl;
}
				
			
An error has occurred!
Error #: 257
Error Message: Syntax error
Error Symbol: +
Error Location: 3
Error Expression: 123+
Syntax error

An error has occurred!
Error #: 8
Error Message: Division by 0
Error Symbol: 
Error Location: 0
Error Expression: 
Division by 0
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   Public Sub MyErrorHandler(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine("An error has occurred!")
      Console.WriteLine($"Error #: {CInt(uc.Error.Code)}")
      Console.WriteLine($"Error Message: {uc.Error.Message}")
      Console.WriteLine($"Error Symbol: {uc.Error.Symbol}")
      Console.WriteLine($"Error Location: {uc.Error.Location}")
      Console.WriteLine($"Error Expression: {uc.Error.Expression}")
   End Sub
   
   Public Sub Main()
      Dim uc As New uCalc()
      uc.Error.AddHandler(AddressOf MyErrorHandler)
      Console.WriteLine(uc.EvalStr("123+"))
      Console.WriteLine("")
      
      uc.Error.TrapOnDivideByZero = true
      Console.WriteLine(uc.EvalStr("5/0"))
   End Sub
End Module
				
			
An error has occurred!
Error #: 257
Error Message: Syntax error
Error Symbol: +
Error Location: 3
Error Expression: 123+
Syntax error

An error has occurred!
Error #: 8
Error Message: Division by 0
Error Symbol: 
Error Location: 0
Error Expression: 
Division by 0
Registers a handler to log when division by zero occurs.
				
					using uCalcSoftware;

var uc = new uCalc();

static void LogAndResume(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine($"Logged error: {uc.Error.Message}");
   uc.Error.Response = ErrorHandlerResponse.Resume;
}


uc.Error.TrapOnDivideByZero = true;
uc.Error.AddHandler(LogAndResume);

Console.WriteLine("Start");
var Result = uc.Eval("5/0");   // Division by zero
Console.WriteLine("End");
				
			
Start
Logged error: Division by 0
End
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call LogAndResume(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "Logged error: " << uc.Error().Message() << endl;
   uc.Error().Response(ErrorHandlerResponse::Resume);
}

int main() {
   uCalc uc;
   uc.Error().TrapOnDivideByZero(true);
   uc.Error().AddHandler(LogAndResume);

   cout << "Start" << endl;
   auto Result = uc.Eval("5/0");   // Division by zero
   cout << "End" << endl;
}
				
			
Start
Logged error: Division by 0
End
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   Public Sub LogAndResume(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine($"Logged error: {uc.Error.Message}")
      uc.Error.Response = ErrorHandlerResponse.Resume
   End Sub
   
   Public Sub Main()
      Dim uc As New uCalc()
      uc.Error.TrapOnDivideByZero = true
      uc.Error.AddHandler(AddressOf LogAndResume)
      
      Console.WriteLine("Start")
      Dim Result = uc.Eval("5/0")   '// Division by zero
      Console.WriteLine("End")
   End Sub
End Module
				
			
Start
Logged error: Division by 0
End
Error handler to auto-define variables
				
					using uCalcSoftware;

var uc = new uCalc();

// This error handler allows you to use variables that were not
// explicitly defined previously, by defining the unrecognized identifiers
// as variables instead of returning an error
static void AutoVariableDef(Handle_uCalc h) {
   var uc = new uCalc(h);
   if (uc.Error.Code == ErrorCode.Undefined_Identifier) {
      uc.DefineVariable(uc.Error.Symbol);
      uc.Error.Response = ErrorHandlerResponse.Resume;
   }
}


uc.Error.AddHandler(AutoVariableDef);
Console.WriteLine(uc.Eval("AutoTest = 123"));
Console.WriteLine(uc.Eval("AutoTest * 1000"));
				
			
123
123000
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

// This error handler allows you to use variables that were not
// explicitly defined previously, by defining the unrecognized identifiers
// as variables instead of returning an error
void ucalc_call AutoVariableDef(Handle_uCalc h) {
   auto uc = uCalc(h);
   if (uc.Error().Code() == ErrorCode::Undefined_Identifier) {
      uc.DefineVariable(uc.Error().Symbol());
      uc.Error().Response(ErrorHandlerResponse::Resume);
   }
}

int main() {
   uCalc uc;
   uc.Error().AddHandler(AutoVariableDef);
   cout << uc.Eval("AutoTest = 123") << endl;
   cout << uc.Eval("AutoTest * 1000") << endl;
}
				
			
123
123000
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   '// This error handler allows you to use variables that were not
   '// explicitly defined previously, by defining the unrecognized identifiers
   '// as variables instead of returning an error
   Public Sub AutoVariableDef(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      If uc.Error.Code = ErrorCode.Undefined_Identifier Then
         uc.DefineVariable(uc.Error.Symbol)
         uc.Error.Response = ErrorHandlerResponse.Resume
      End If
   End Sub
   
   Public Sub Main()
      Dim uc As New uCalc()
      uc.Error.AddHandler(AddressOf AutoVariableDef)
      Console.WriteLine(uc.Eval("AutoTest = 123"))
      Console.WriteLine(uc.Eval("AutoTest * 1000"))
   End Sub
End Module
				
			
123
123000
Error handler order
				
					using uCalcSoftware;

var uc = new uCalc();

static void ErrorHandlerA(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine("Handler A called");
}

static void ErrorHandlerB(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine("Handler B called");
}

static void ErrorHandlerC(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine("Handler C called");
}

static void ErrorHandlerD(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine("Handler D called");
}

static void ErrorHandlerE(Handle_uCalc h) {
   var uc = new uCalc(h);
   Console.WriteLine("Handler E called");
}


uc.Error.AddHandler(ErrorHandlerA);
uc.Error.AddHandler(ErrorHandlerB);
uc.Error.AddHandler(ErrorHandlerC);
uc.Error.AddHandler(ErrorHandlerD, -1);
uc.Error.AddHandler(ErrorHandlerE, 3);

Console.WriteLine(uc.EvalStr("10 / "));
				
			
Handler C called
Handler B called
Handler A called
Handler E called
Handler D called
Syntax error
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

void ucalc_call ErrorHandlerA(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "Handler A called" << endl;
}

void ucalc_call ErrorHandlerB(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "Handler B called" << endl;
}

void ucalc_call ErrorHandlerC(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "Handler C called" << endl;
}

void ucalc_call ErrorHandlerD(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "Handler D called" << endl;
}

void ucalc_call ErrorHandlerE(Handle_uCalc h) {
   auto uc = uCalc(h);
   cout << "Handler E called" << endl;
}

int main() {
   uCalc uc;
   uc.Error().AddHandler(ErrorHandlerA);
   uc.Error().AddHandler(ErrorHandlerB);
   uc.Error().AddHandler(ErrorHandlerC);
   uc.Error().AddHandler(ErrorHandlerD, -1);
   uc.Error().AddHandler(ErrorHandlerE, 3);

   cout << uc.EvalStr("10 / ") << endl;
}
				
			
Handler C called
Handler B called
Handler A called
Handler E called
Handler D called
Syntax error
				
					Imports System
Imports uCalcSoftware
Public Module Program
   
   Public Sub ErrorHandlerA(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine("Handler A called")
   End Sub
   
   Public Sub ErrorHandlerB(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine("Handler B called")
   End Sub
   
   Public Sub ErrorHandlerC(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine("Handler C called")
   End Sub
   
   Public Sub ErrorHandlerD(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine("Handler D called")
   End Sub
   
   Public Sub ErrorHandlerE(ByVal h As Handle_uCalc)
      Dim uc As New uCalc(h)
      Console.WriteLine("Handler E called")
   End Sub
   
   Public Sub Main()
      Dim uc As New uCalc()
      uc.Error.AddHandler(AddressOf ErrorHandlerA)
      uc.Error.AddHandler(AddressOf ErrorHandlerB)
      uc.Error.AddHandler(AddressOf ErrorHandlerC)
      uc.Error.AddHandler(AddressOf ErrorHandlerD, -1)
      uc.Error.AddHandler(AddressOf ErrorHandlerE, 3)
      
      Console.WriteLine(uc.EvalStr("10 / "))
   End Sub
End Module
				
			
Handler C called
Handler B called
Handler A called
Handler E called
Handler D called
Syntax error