Mercurial > octave
diff liboctave/util/quit.h @ 27471:fd32c1a9b1bd
revamp error handling
In "error" and similar functions that ultimately call it, simply throw
an exception that contains information about the error (message, id,
stack info) instead of printing an error message immediately and then
throwing an exception. The new approach is more flexible and sllows
for some simplification of the error message routines as they no
longer need feedback from the interpreter to know when to display or
buffer messages. It is now the responsibility of any code that
catches an execution exception to determine whether and when to
display error messages.
* quit.h, quit.cc (class frame_info): New class.
(execution_exception::m_err_type, execution_exception::m_id,
execution_exception::m_message, execution_exception::m_stack_info):
New data members.
(class execution_exception): Store error type, message, id, and stack
info. Provide methods setting and accessing data as needed and for
generating stack trace message from stack info.
(execution_exception::m_stack_trace): Delete data member.
execution_exception::set_stack_trace): Delete method.
(execution_exception::set_err_type, execution_exception::err_type,
execution_exception::stack_trace, execution_exception::set_identifier,
execution_exception::identifier, execution_exception::message,
execution_exception::set_stack_info, execution_exception::display):
New methods.
* call-stack.cc, call-stack.h (call_stack::backtrace_info):
New functions.
* oct-parse.yy (maybe_print_last_error_message): Delete function and
all uses.
* pt-eval.h, pt-eval.cc (tree_evaluator::backtrace_info,
tree_evaluator::backtrace_message): New functions.
(tree_evaluator::backtrace): Now const.
(tree_evaluator::visit_unwind_protect_command,
tree_evaluator::do_unwind_protect_cleanup_code,
tree_evaluator::visit_try_catch_command, tree_evaluator::evalin,
tree_evaluator::eval, tree_evaluator::repl, debugger::repl): Save
current exception info.
* interpreter.h, interpreter.cc (interpreter::handle_exception):
New function. Use it in place of direct calls to
error_system::save_exception, error_system::display_exception (or
execution_exception::display) and interpreter::recover_from_exception,
so that we have uniform behavior when responding to an execution
exception.
* error.h, error.cc (error_system::m_buffer_error_messages,
error_system::m_discard_error_messages, error_system::m_in_try_catch):
Delete data members and associated functions. Remove all uses.
Because the error system no longer displays messages immediately,
it does not need to track whether to discard or buffer error messages
or know whether error and warning functions are invoked inside of
try-catch blocks. Everywhere that catches execution_exceptions must
now handle saving the exception state (for lasterror) and displaying
the error message and traceback as needed.
(): Delete functions and all uses.
(error_stack_frame): Delete struct definition.
(verror, vpr_where, pr_where_internal, pr_where, maybe_enter_debugger,
make_execution_exception, vmessage_with_id, message_with_id,
error_system::maybe_enter_debugger, reset_error_handler,
error_system::reset): Delete functions and all uses.
(error_system::try_option): Delete enum and all uses.
(vusage, error_1, error_system::vwarning,
error_system::rethrow_error, error_system::interpreter_try):
Simplify.
(format_message, make_stack_map, error_system::throw_error,
error_system::save_exception, error_system::display_exception):
New functions.
(Ferror): Update for error_system changes.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 04 Oct 2019 01:15:13 -0400 |
parents | d4fdaeaab7f3 |
children | 63b417917f5e |
line wrap: on
line diff
--- a/liboctave/util/quit.h Fri Oct 04 00:30:34 2019 -0400 +++ b/liboctave/util/quit.h Fri Oct 04 01:15:13 2019 -0400 @@ -28,6 +28,8 @@ /* The signal header is just needed for the sig_atomic_t type. */ #if defined (__cplusplus) # include <csignal> +# include <iosfwd> +# include <list> # include <string> extern "C" { #else @@ -38,12 +40,65 @@ namespace octave { + class frame_info + { + public: + + frame_info (void) = default; + + frame_info (const std::string& file_name, const std::string& fcn_name, + int line, int column) + : m_file_name (file_name), m_fcn_name (fcn_name), m_line (line), + m_column (column) + { } + + frame_info (const frame_info&) = default; + + frame_info& operator = (const frame_info&) = default; + + ~frame_info (void) = default; + + std::string file_name (void) const { return m_file_name; } + + std::string fcn_name (void) const { return m_fcn_name; } + + int line (void) const { return m_line; } + + int column (void) const { return m_column; } + + private: + + std::string m_file_name; + + std::string m_fcn_name; + + int m_line; + + int m_column; + }; + + inline bool operator == (const frame_info& a, const frame_info& b) + { + return (a.file_name () == b.file_name () + && a.fcn_name () == b.fcn_name () + && a.line () == b.line () + && a.column () == b.column ()); + } + class execution_exception { public: - execution_exception (void) = default; + typedef std::list<frame_info> stack_info_type; + + execution_exception (const std::string& err_type = "error", + const std::string& id = "", + const std::string& message = "unspecified error", + const stack_info_type& stack_info = stack_info_type ()) + : m_err_type (err_type), m_id (id), m_message (message), + m_stack_info (stack_info) + { } execution_exception (const execution_exception&) = default; @@ -51,24 +106,50 @@ ~execution_exception (void) = default; - virtual void set_stack_trace (const std::string& st) + void set_err_type (const std::string& et) { - m_stack_trace = st; + m_err_type = et; + } + + std::string err_type (void) const { return m_err_type; } + + virtual std::string stack_trace (void) const; + + void set_identifier (const std::string& id) + { + m_id = id; } - virtual void set_stack_trace (void) + virtual std::string identifier (void) const { return m_id; } + + void set_message (const std::string& msg) { - m_stack_trace = ""; + m_message = msg; } - virtual std::string info (void) const + virtual std::string message (void) const { return m_message; } + + virtual stack_info_type stack_info (void) const { - return m_stack_trace; + return m_stack_info; } + void set_stack_info (const stack_info_type& stack_info) + { + m_stack_info = stack_info; + } + + virtual void display (std::ostream& os) const; + private: - std::string m_stack_trace; + std::string m_err_type; + + std::string m_id; + + std::string m_message; + + stack_info_type m_stack_info; }; class