List:Internals« Previous MessageNext Message »
From:Marc Alff Date:October 20 2009 2:33am
Subject:Re: help -- how do I return an error?
View as plain text  
Hi Mark

MARK CALLAGHAN wrote:
> I want to return an error in the patch I submitted for
> http://bugs.mysql.com/bug.php?id=48124
> This document appears to be out of date:
> http://forge.mysql.com/wiki/MySQL_Internals_Error_Messages
>
> How do I return an error for a SQL command? There is my_message,
> my_error, my_printf_error and push_warning in MySQL source. Most of
> these are not described by the URL above.
>   

To raise an error:

Without parameters:
  my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0));

With parameters:
    my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
           MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);

To raise a warning:

Without parameters:
  push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
    ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));

With parameters:
   push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
     ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED),
     main_view->view_db.str, main_view->view_name.str);

If you use code starting in 5.5, you may look at THD::raise_error() and
friends also.

Things to avoid (and yes, there are plenty of bad examples in the code):
- "ER_XXX, "plain text" --> should be ER_XXX, ER(ER_XXX), and the text
should be in errmsg.txt
- printf in buffer + "ER_XXX, buffer" --> likewise
- push_warning / push_warning_printf with a level of WARN_LEVEL_ERROR:
that's a bug.

Now, the real issue is if you want to return a *new* error.

This area, and the process around it to allow everybody to change the
code while keeping compatibility between releases (and have the same
error numbers for the same thing) is a major pain point, still unresolved.

Below is the procedure used by development:

The first step is to add an entry in the file sql/share/errmsg.txt, at
the *end*.

This is important so that the message text is not hard coded in the
source, and can be translated for other languages.

For example:
ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER 0K000
        eng "RESIGNAL when handler not active"

"0K000" is optional, it's the SQLSTATE for this error.

Errors should be named ER_XXX, warnings WARN_XXX (not always followed).

The next question is whether the message contains printf-like parameters
or not.
When using %s parameters, please consider a max size like "%-.64s"
instead of just "%s" to protect from overflows when printing the message
with bad data.

This is for releases that are not GA yet, since creating new error codes
has no impact on existing applications.

For code already GA, if you follow this, then it will create merge
issues between your errmsg.txt and mysql errmsg.txt, and create
conflicts with error numbering later, which is why the generic
ER_UNKNOWN_ERROR + hard coded message text is suggested.
Keep in mind that even if conflicts may not visible now, they will
happen at the next upgrade, so this area is sensitive.

For new errors, to maintain compatibility, the choices are then limited to:

my_printf_error(ER_UNKNOWN_ERROR,
  "Some error text here, without parameters",
  MYF(0));

my_printf_error(ER_UNKNOWN_ERROR,
  "Some error text here, with the '%-.64s' parameter value"
   MYF(0), a_parameter);

push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
    ER_UNKNOWN_ERROR, "Some warning text here, without parameters");

push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
     ER_UNKNOWN_ERROR, "Some warning text here, with the '%-.64s'
parameter value",
     a_parameter);

There are still several problems here:
- the text is hard coded again (no hope of translation),
- there is only 1 error code to choose from, which makes it hard for an
application to sort things out if several enhancements needs new errors
for different things, and if a client / stored procedure needs special
logic based on the error *code* (as opposed to a human looking at the
error *text*).

All this is only a work around, if there is no existing error message
from errmsg.txt that can be reused, so the best hope is to find a "close
enough" existing message :(

Regards,
-- Marc

Thread
help -- how do I return an error?MARK CALLAGHAN20 Oct
  • Re: help -- how do I return an error?Marc Alff20 Oct
    • Re: help -- how do I return an error?Konstantin Osipov20 Oct
    • Re: help -- how do I return an error?MARK CALLAGHAN28 Oct
      • Re: help -- how do I return an error?Marc Alff29 Oct
        • Re: help -- how do I return an error?Michael Widenius31 Oct
          • Re: help -- how do I return an error?MARK CALLAGHAN31 Oct