Thread: error codes

error codes

From
nconway@klamath.dyndns.org (Neil Conway)
Date:
I'd like to implement error codes. I think they would be pretty useful,
although there are a few difficulties in the implementation I'd like
to get some input on.

Should every elog() have an error code? I'm not sure -- there are many
elog() calls that will never been seen by the user, since the error
they represent will be caught before control reaches the elog (e.g.
parse errors, internal consistency checks, multiple elog(ERROR)
for the same user error, etc.) Perhaps for those error messages
that don't have numbers, we could just give them ERRNO_UNKNOWN or
a similar constant.

How should the backend code signal an error with an error number?
Perhaps we could report errors with error numbers via a separate
function, which would take the error number as its only param.
For example:

error(ERRNO_REF_INT_VIOLATION);

The problem here is that many errors will require more information
that that, in order for the client to handle them properly. For
example, how should a COPY indicate that an RI violation has
occured? Ideally, we'd like to allow the client application to
know that in line a, column b, the literal value 'c' was
not found in the referenced column d of the referenced table d.

How should the error number be sent to the client, and would this
require an FE/BE change? I think we can avoid that: including the
error number in the error message itself, make PQgetErrorMessage()
(and similar funcs) smart enough to remove the error number, and
add a separate function (such as PQgetErrorNumber() ) to report
the error number, if there is one.

On a related note, it would be nice to get a consistent style of
punctuation for elog() messages -- currently, some of them end
in a period (e.g. "Database xxx does not exist in the system
catalog."), while the majority do not. Which is better?

Also, I think it was Bruce who mentioned that it would be nice
to add function names, source files, and/or line numbers to error
messages, instead of the current inconsistent method of sometimes
specifying the function name in the elog() message. Would this
be a good idea? Should all errors include this information?

It would be relatively easy to replace elog() with a macro of
the form:

#define elog(...) real_elog(__FILE__, __LINE__, __VA_ARGS__)

And then adjust real_elog() to report that information as
appropriate.

Cheers,

Neil

-- 
Neil Conway <neilconway@rogers.com>
PGP Key ID: DB3C29FC


Re: error codes

From
Tom Lane
Date:
nconway@klamath.dyndns.org (Neil Conway) writes:
> Should every elog() have an error code?

I believe we decided that it'd be okay to use one or two codes defined
like "internal error", "corrupted data", etc for all the elogs that are
not-supposed-to-happen conditions.  What error codes are really for is
distinguishing different kinds of user mistakes, and so that's where
you need specificness.

> How should the backend code signal an error with an error number?

Please read some of the archived discussions about this.  All the points
you mention have been brought up before.
        regards, tom lane


Re: error codes

From
nconway@klamath.dyndns.org (Neil Conway)
Date:
On Wed, Jul 17, 2002 at 03:57:56PM -0400, Tom Lane wrote:
> nconway@klamath.dyndns.org (Neil Conway) writes:
> > Should every elog() have an error code?
> 
> I believe we decided that it'd be okay to use one or two codes defined
> like "internal error", "corrupted data", etc for all the elogs that are
> not-supposed-to-happen conditions.

Ok, makes sense to me.

> > How should the backend code signal an error with an error number?
> 
> Please read some of the archived discussions about this.  All the points
> you mention have been brought up before.

Woops -- I wasn't aware that this had been discussed before, my apologies.
I'm reading the archives now...

Peter: are you planning to implement this?

Cheers,

Neil

-- 
Neil Conway <neilconway@rogers.com>
PGP Key ID: DB3C29FC


Re: error codes

From
Bruce Momjian
Date:
Neil, attached are three email messages dealing with error message
wording.

I like Tom's idea of coding only the messages that are common/user
errors and leaving the others with a catch-all code.

We now have more elog levels in 7.3, so it should be easier to classify
the messages.

I can see this job as several parts:

---------------------------------------------------------------------------

Cleanup of error wording, removal of function names.  See attached
emails for possible standard.

---------------------------------------------------------------------------

Reporting of file, line, function reporting using GUC/SET variable.  For
function names I see in the gcc 3.1 docs at
http://gcc.gnu.org/onlinedocs/gcc-3.1/cpp/Standard-Predefined-Macros.html:

    C99 introduces __func__, and GCC has provided __FUNCTION__ for a long
    time. Both of these are strings containing the name of the current
    function (there are slight semantic differences; see the GCC manual).
    Neither of them is a macro; the preprocessor does not know the name of
    the current function. They tend to be useful in conjunction with
    __FILE__ and __LINE__, though.

My gcc 2.95 (gcc version 2.95.2 19991024) supports both __FUNCTION__ and
__func__, even though they are not documented in the info manual pages I
have.  I think we will need a configure.in test for this because it
isn't a macro you can #ifdef.

---------------------------------------------------------------------------

Actual error code numbers/letters.  I think the new elog levels will
help with this.  We have to decide if we want error numbers, or some
pneumonic like NOATTR or CONSTVIOL.  I suggest the latter.

---------------------------------------------------------------------------

I think we have plenty of time to get this done for 7.3.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: error codes

From
Peter Eisentraut
Date:
Neil Conway writes:

> I'd like to implement error codes. I think they would be pretty useful,
> although there are a few difficulties in the implementation I'd like
> to get some input on.

OK, allow me to pass on to you the accumulated wisdom on this topic. :-)

> Should every elog() have an error code?

The set of error codes should primarily be that defined by SQL99 part 2
clause 22 "Status codes" and PostgreSQL extensions that follow that
spirit.  That means that all those "can't happen" or "all is lost anyway"
types should be lumped (perhaps in some implicit way) under "internal
error".  That means, yes, an error code should be returned in every case
of an error, but it doesn't have to be a distinct error code for every
condition.

> How should the backend code signal an error with an error number?

> The problem here is that many errors will require more information
> that that, in order for the client to handle them properly. For
> example, how should a COPY indicate that an RI violation has
> occured? Ideally, we'd like to allow the client application to
> know that in line a, column b, the literal value 'c' was
> not found in the referenced column d of the referenced table d.

Precisely.  You will find that SQL99 part 2 clause 19 "Diagnostics
management" defines all the fields that form part of a diagnostic (i.e.,
error or notice).  This includes for example, fields that contain the name
and schema of the table that was involved, if appropriate.  (Again,
appropriate PostgreSQL extensions could be made.)  It is recommendable
that this scheme be followed, so PL/pgSQL and ECPG, to name some
candidates, could implement the GET DIAGNOSTICS statement as in the
standard.  (Notice that, for example, a diagnostic still contains a text
message in addition to a code.)

> How should the error number be sent to the client, and would this
> require an FE/BE change? I think we can avoid that: including the
> error number in the error message itself, make PQgetErrorMessage()
> (and similar funcs) smart enough to remove the error number, and
> add a separate function (such as PQgetErrorNumber() ) to report
> the error number, if there is one.

I would advise against trying to cram everything into a string.  Consider
the extra fields explained above.  Consider being nice to old clients.
Also, libpq allows that more than one error message might arrive per query
cycle.  Currently, the error messages are concatenated.  That won't work
anymore.  You need a new API anyway.  You need a new API for notices, too.

One possiblity to justify a protocol change is to break something else
with it, like a new copy protocol.

> On a related note, it would be nice to get a consistent style of
> punctuation for elog() messages -- currently, some of them end
> in a period (e.g. "Database xxx does not exist in the system
> catalog."), while the majority do not. Which is better?

Yup, we've talked about that some time ago.  I have a style guide mostly
worked out for discussion.

> It would be relatively easy to replace elog() with a macro of
> the form:
>
> #define elog(...) real_elog(__FILE__, __LINE__, __VA_ARGS__)
>
> And then adjust real_elog() to report that information as
> appropriate.

And it would be relatively easy to break every old compiler that way...

-- 
Peter Eisentraut   peter_e@gmx.net



Re: error codes

From
"Christopher Kings-Lynne"
Date:
> Should every elog() have an error code? I'm not sure -- there are many
> elog() calls that will never been seen by the user, since the error
> they represent will be caught before control reaches the elog (e.g.
> parse errors, internal consistency checks, multiple elog(ERROR)
> for the same user error, etc.) Perhaps for those error messages
> that don't have numbers, we could just give them ERRNO_UNKNOWN or
> a similar constant.

It might be cool to a little command utility "pg_error" or whatever that you
pass an error code to and it prints out a very detailed description of the
problem...

Chris



Re: error codes

From
"Zeugswetter Andreas SB SD"
Date:
Bruce wrote:
> Actual error code numbers/letters.  I think the new elog levels will
> help with this.  We have to decide if we want error numbers, or some
> pneumonic like NOATTR or CONSTVIOL.  I suggest the latter.

Since there is an actual standard for error codes, I would strongly suggest
to adhere. The standardized codes are SQLSTATE a char(5) (well standardized
for many classes of db errors). Also common, but not so standardized is SQLCODE
a long (only a very few are standardized, like 100 = 'no data found').
And also sqlca. Also look at ecpg for sqlcode and sqlca.

A Quote from dec rdb:
--------------------------------------------------------------------  o  SQLCODE-This is the original SQL error
handlingmechanism.     It is an integer value. SQLCODE differentiates among errors     (negative numbers), warnings
(positivenumbers), succesful     completion (0), and a special code of 100, which means no     data. SQLCODE is a
deprecatedfeature of the ANSI/ISO SQL     standard. 
  o  SQLCA-This is an extension of the SQLCODE error handling     mechanism. It contains other context information that
   supplements the SQLCODE value. SQLCA is not part of the     ANSI/ISO SQL standard. However, many foreign databases
such    as DB2 and ORACLE RDBMS have defined proprietary semantics and     syntax to implement it. 
  o  SQLSTATE-This is the error handling mechanism for the ANSI/ISO     SQL standard. The SQLSTATE value is a character
stringthat is     associated with diagnostic information. To use the SQLSTATE     status parameter, you must specify
theSQL92 dialect and     compile your module using DEC Rdb Version 6.0. 
--------------------------------------------------------------------

Andreas


Re: error codes

From
Fernando Nasser
Date:
Insisting on Andreas suggestion,  why can't we just prefix all error message 
strings with the SQLState code?  So all error messages would have the format

CCSSS - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Where CCSSS is the standard SQLState code and the message text is a more 
specific description.

Note that the standard allows for implementation-defined codes, so we can have 
our own CC classes and all the SSS subclasses that we need.


-- 
Fernando Nasser
Red Hat - Toronto                       E-Mail:  fnasser@redhat.com
2323 Yonge Street, Suite #300
Toronto, Ontario   M4P 2C9