MySQL Internals Manual  /  ...  /  Exception Handling

16.7.4 Exception Handling

When the code enters a block protected by a HANDLER, the execution leads to sp_instr_hpush_jump::execute(), which installs the exception handler in the runtime handler stack, by calling sp_rcontext::push_handler().

In a similar way, when the code leaves a block protected by a HANDLER, sp_instr_hpop::execute() removes the handlers installed by the matching sp_instr_hpush_jump, by calling sp_rcontext::pop_handlers().

During the execution of any statement, different CONDITION can be raised at runtime, which are reported by the implementation of each statement by calling push_warning(), my_error() or similar functions. All these entry points ultimately leads to the error handler hook callback function implemented by error_handler_hook in mysys/my_error.c. In case of the server itself, this hook points to the function my_message_sql().

Under normal circumstances, my_message_sql() just reports a warning or an error to the client application, and for errors causes the query to abort.

When executing a stored program, THD::spcont points to the runtime context of the program currently executed. When a HANDLER is active, the runtime context contains in its handler stack the list of all the CONDITIONs currently trapped, giving a chance to the call to sp_rcontext::handle_error() to intercept error handling.

If the condition reported does not match any of the conditions for which an exception handler is active, sp_rcontext::handle_error() returns false, and my_message_sql() raises the error or warning as usual.

When the condition reported does match an active HANDLER, that handler is called, but the technical nature of this call is special: the call is asynchronous. Instead of invoking the exception handler directly, sp_rcontext::handle_error() marks which exception handler is to be called, by setting the member variable sp_rcontext::m_hfound, and then returns true, so that my_message_sql() returns without reporting anything: at this point, the error condition has been totally masked, except for the fact that sp_rcontext::m_hfound is set.

Once my_message_sql() returns, the implementation of a given statement continues, either by proceeding if only a warning was reported, or by aborting the current execution if an error was raised. The execution of code in the server will eventually return from the implementation of a statement, and return from the call to sp_instr::execute() for that statement, returning control to the loop located in sp_head::execute(). Note that during the execution of the code that follows a call to my_message_sql(), error conditions are propagated in the call stack though the function's return value. It is transparent to the implementation of statements in general whether an exception was caught by an error handler.

After an instruction is executed in sp_head::execute(), the main interpreter loop checks for any pending exception handler code to call, by invoking sp_rcontext::found_handler(). If an exception was caught, the handler to call has been found by sp_rcontext::handle_error(), and is invoked.

In case of CONTINUE HANDLER, the instruction to return to after the handler code is executed needs to be saved in the runtime context. Finding the continuation destination is accomplished by the call to sp_instr::get_cont_dest() for the current instruction, whereas preserving this destination is done with sp_rcontext::push_hstack(). The matching call to sp_rcontext::pop_hstack(), which is executed when the exception handler is done, is located in sp_instr_hreturn::execute().


To integrate properly with exception handling in general, the code should avoid testing for thd->net.report_error, or worse inspecting the content of the error stack (displayed by SHOW ERRORS), because doing this actually assumes not only that an error was raised, but also that it was not caught. Instead, the proper way to implement error handling in the server is to return error status values and check for them.

User Comments
Sign Up Login You must be logged in to post a comment.