uCalc API Version: 2.1.3-preview.2 Released: 6/17/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:
Class:
Registers a callback function to intercept, log, or resolve errors during parsing and evaluation.
Syntax
Parameters
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:
- Most recently added handler first
- 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:
ErrorLocation→0ErrorExpression→ empty stringErrorSymbol→ 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 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"));
#include
#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 #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; }
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 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
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 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");
#include
#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 #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; }
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 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
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 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"));
#include
#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 #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; }
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 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
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 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 / "));
#include
#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 #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; }
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 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