How to Handle Errors and Use the error_manager Module in Nelson
The error_manager module in Nelson provides a MATLAB-compatible error-handling infrastructure that bridges low-level C++ exceptions with high-level script functions like error, warning, throw, lasterror, and lastwarn.
The nelson-lang/nelson repository implements a robust error-handling system that allows developers to handle errors and use the error_manager module in Nelson scripts through both simple function calls and advanced exception management. This architecture captures stack traces, supports warning states, and enables precise error filtering through the MException class.
Architecture of the error_manager Module
The error_manager module operates across four distinct architectural layers that translate between C++ exceptions and script-level error objects.
The Public C++ API layer, defined in modules/error_manager/src/include/Error.hpp and Error.cpp, provides the Error() and Warning() functions. These capture the current call stack from the Evaluator and throw Nelson::Exception objects. The Exception type layer implements MException in MException.hpp, providing MATLAB-compatible conversion helpers like ArrayOfToException and ExceptionToArrayOf that translate between C++ exceptions and script structs.
The Gateway layer contains builtin implementations such as throwBuiltin.cpp and warningBuiltin.cpp that parse script arguments and invoke the C++ API. This layer also manages warning state machinery through warning('on'), warning('off'), and warning('aserror') commands. Finally, the State storage layer uses the NelsonConfiguration singleton to persist the last warning exception and warning-state maps, enabling lastwarn and lasterror functionality.
Raising Errors and Warnings in Nelson Scripts
Raising a Simple Error
When a script calls error('message'), the builtin gateway in modules/error_manager/builtin/cpp/errorBuiltin.cpp forwards the request to the C++ Error function. This constructs a DebugStack from the current call stack and throws a Nelson::Exception, halting execution immediately.
% Raise a fatal error
error('File not found');
The interpreter catches the C++ exception and displays:
Error: File not found
Configuring Warnings as Errors
The warning function controls emission behavior through three states: on, off, and aserror. In warningBuiltin.cpp, the gateway stores states in NelsonConfiguration. When warning('aserror', 'id') is set, the Warning C++ class checks the state via warningCheckState() and routes to Error() instead of emitting a warning.
% Set warning "my:warn" to behave as an error
warning('on') % default – enabled
warning('aserror','my:warn');
% This now raises an error instead of a warning
warning('my:warn','Something is odd');
Throwing MException Objects
The throw function re-raises existing MException objects while preserving the original identifier and message. The implementation in throwBuiltin.cpp detects scalar MException structs, uses ArrayOfToException to convert back to a C++ Exception, attaches the current stack trace via DebugStack(eval->callstack,1,trace), and re-throws.
% Create an MException
ME = MException('my:Error','Bad value');
% Re-throw it
throw(ME);
Capturing and Querying Errors
Using Try-Catch Blocks
Nelson supports MATLAB-compatible try-catch syntax. When the interpreter catches a C++ exception, it converts the Exception to an MException struct using ExceptionToArrayOf, making the message, identifier, and stack fields available in the catch clause.
try
error('Oops');
catch ME
disp(['Caught: ' ME.message]); % prints "Caught: Oops"
disp(['Identifier: ' ME.identifier]); % prints "Identifier: "
end
Retrieving Last Warning and Error States
The lastwarn and lasterror functions query persistent state stored in the NelsonConfiguration singleton. lastwarn retrieves the most recent warning exception, while lasterror accesses the last caught exception from the evaluator.
% Emit a warning
warning('my:warn', 'Something');
% Retrieve it
[wmsg, wid] = lastwarn; % wmsg = "Something", wid = "my:warn"
% Retrieve last error after catch
try
error('Bad');
catch
e = lasterror;
disp(e.message); % "Bad"
disp(e.identifier);% ""
end
Key Implementation Files
The error_manager module spans several critical paths in the nelson-lang/nelson repository:
modules/error_manager/src/include/Error.hppandError.cpp– Core C++ API for raising errors with stack trace capture viaDebugStack.modules/error_manager/src/include/Warning.hppandWarning.cpp– Warning emission logic, state checking viawarningCheckState, and conversion to error when configured asaserror.modules/error_manager/src/include/MException.hpp– Conversion utilitiesArrayOfToExceptionandExceptionToArrayOfbetween C++ exceptions and script structs.modules/error_manager/builtin/cpp/throwBuiltin.cpp– Script-levelthrowimplementation for re-raisingMExceptionobjects.modules/error_manager/builtin/cpp/warningBuiltin.cpp– Gateway forwarningstate management and emission modes.modules/error_manager/help/en_US/xml/– Documentation source files for user-facing error handling functions.
Summary
- The error_manager module provides Nelson's complete error-handling infrastructure, bridging low-level C++ exceptions with high-level script functions through the
ErrorandWarningclasses. - Use
error('msg')for fatal errors andwarning('msg')for recoverable issues, withwarning('aserror','id')to upgrade specific warnings to errors. - Capture exceptions using
try-catchblocks where the catch variable receives an MException struct containing message, identifier, and stack fields. - Query recent errors and warnings via
lasterrorandlastwarn, which access state stored in the core NelsonConfiguration singleton.
Frequently Asked Questions
How do I convert a warning into a fatal error in Nelson?
Use the warning('aserror', 'identifier') syntax to map a specific warning ID to error behavior. When that warning is subsequently triggered, the Warning C++ class in Warning.cpp checks the state via warningCheckState and routes to the Error function, causing execution to halt immediately rather than continuing with a warning message.
What is the difference between error and throw in Nelson?
The error function creates a new exception with the current call stack and immediately halts execution. The throw function re-raises an existing MException object, preserving its original identifier and message while attaching the current stack trace via DebugStack in throwBuiltin.cpp—useful for re-throwing exceptions in catch blocks without losing the original error context.
How does Nelson store the last warning and error states?
Nelson uses the NelsonConfiguration singleton to persist state across the interpreter session. The lastwarn function retrieves the most recent warning exception from this configuration, while lasterror accesses the last caught exception from the evaluator's state. These functions enable scripts to inspect errors after they occur or outside of immediate try-catch blocks.
Can I customize the identifier when raising an error?
Yes. While the simple error('message') form uses an empty identifier, you can create custom exceptions with specific identifiers using the MException class. Construct the exception with MException('identifier', 'message') and then use throw(ME) to raise it with the custom identifier intact, enabling precise error filtering in catch blocks based on the identifier field.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →