diff --git a/Mcode/+logger/Logger.m b/Mcode/+logger/Logger.m index fcc2ae83..3e29c4bc 100644 --- a/Mcode/+logger/Logger.m +++ b/Mcode/+logger/Logger.m @@ -106,8 +106,14 @@ function error(this, msg, varargin) if ~this.jLogger.isErrorEnabled() return end - msgStr = formatMessage(msg, varargin{:}); - this.jLogger.error(msgStr); + try + msgStr = formatMessage(msg, varargin{:}); + this.jLogger.error(msgStr); + catch ME + if logger.raiseExceptions + throw(ME) + end + end end function warn(this, msg, varargin) @@ -115,8 +121,14 @@ function warn(this, msg, varargin) if ~this.jLogger.isWarnEnabled() return end - msgStr = formatMessage(msg, varargin{:}); - this.jLogger.warn(msgStr); + try + msgStr = formatMessage(msg, varargin{:}); + this.jLogger.warn(msgStr); + catch ME + if logger.raiseExceptions + throw(ME) + end + end end function info(this, msg, varargin) @@ -124,8 +136,14 @@ function info(this, msg, varargin) if ~this.jLogger.isInfoEnabled() return end - msgStr = formatMessage(msg, varargin{:}); - this.jLogger.info(msgStr); + try + msgStr = formatMessage(msg, varargin{:}); + this.jLogger.info(msgStr); + catch ME + if logger.raiseExceptions + throw(ME) + end + end end function debug(this, msg, varargin) @@ -133,8 +151,14 @@ function debug(this, msg, varargin) if ~this.jLogger.isDebugEnabled() return end - msgStr = formatMessage(msg, varargin{:}); - this.jLogger.debug(msgStr); + try + msgStr = formatMessage(msg, varargin{:}); + this.jLogger.debug(msgStr); + catch ME + if logger.raiseExceptions + throw(ME) + end + end end function trace(this, msg, varargin) @@ -142,8 +166,14 @@ function trace(this, msg, varargin) if ~this.jLogger.isTraceEnabled() return end - msgStr = formatMessage(msg, varargin{:}); - this.jLogger.trace(msgStr); + try + msgStr = formatMessage(msg, varargin{:}); + this.jLogger.trace(msgStr); + catch ME + if logger.raiseExceptions + throw(ME) + end + end end function errorj(this, msg, varargin) diff --git a/Mcode/+logger/raiseExceptions.m b/Mcode/+logger/raiseExceptions.m new file mode 100644 index 00000000..5aa1ca6c --- /dev/null +++ b/Mcode/+logger/raiseExceptions.m @@ -0,0 +1,46 @@ +function varargout = raiseExceptions(newval) +%RAISEEXCEPTIONS gets/sets a flag for handling exceptions during logging +% RAISEEXCEPTIONS gets or sets a flag that is used by the logic that +% controls the handling of exceptions raised/thrown during logging. +% The default flag value is true. +% +% Usage +% % suppress exceptions during logging framework message handling +% logger.raiseExceptions(false) + +%{ +This mechanism is inspired by a comment from Martijn Pieters in +https://stackoverflow.com/questions/66587941/what-happens-if-a-python-logging-handler-raises-an-exception + +"The Python standard-library handlers have been build with robustness in +mind. If an exception is raised ..., all standard library +implementations catch the exception and ... +By default, ... re-raises the exception. In production systems you want +to set logging.raiseExceptions = False, at which point the exceptions +are silently ignored, and logging continues as if nothing happened. + +From the documentation: ... If the module-level attribute +raiseExceptions is False, exceptions get silently ignored. This is what +is mostly wanted for a logging system - most users will not care about +errors in the logging system, they are more interested in application +errors. ... (The default value of raiseExceptions is True, as that is +more useful during development)." +%} + +persistent flag + +if isempty(flag) + flag = true; +end + +switch nargin + case 0 % get + varargout{1} = flag; + case 1 % set + assert(isscalar(newval) & islogical(newval), 'bad usage') + flag = newval; + otherwise + assert(false, 'impossible') +end + +end diff --git a/Mcode/+logger/throwExceptions.m b/Mcode/+logger/throwExceptions.m new file mode 100644 index 00000000..383bfc42 --- /dev/null +++ b/Mcode/+logger/throwExceptions.m @@ -0,0 +1,12 @@ +function varargout = throwExceptions(varargin) +%THROWEXCEPTIONS is an alias for RAISEEXCEPTIONS +% RAISEEXCEPTIONS is inspired by the Python standard library +% framework. +% In MATLAB, exceptions are 'thrown' rather than 'raised', so +% THROWEXCEPTIONS is provided as a more MATLAB-consistent alias. +% +% Usage +% % suppress exceptions during logging framework message handling +% logger.throwExceptions(false) + +[varargout{1:nargout}] = logger.raiseExceptions(varargin{:});