Thread: Can the backend return more than one error message per PQexec?
In PQexec() and also in parseInput() (both fe-exec.c) there is a provision for, if more than one result set is returned, to concatenate the error messages (while only returning the last result set). My question is how a backend can return more than one error message per query string? The description of the protocol indicates that an ErrorResponse will either cause a connection close or the end of a query cycle. I am currently looking into extending the protocol so that more fields can be in an ErrorResponse (e.g., error codes). If this were to happen then we'd need a smarter way of handling more than one error message per cycle. However, I'd rather avoid that case in the first place. -- Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
Peter Eisentraut <peter_e@gmx.net> writes: > In PQexec() and also in parseInput() (both fe-exec.c) there is a provision > for, if more than one result set is returned, to concatenate the error > messages (while only returning the last result set). My question is how a > backend can return more than one error message per query string? That concatenation hack was added to deal with an actual case where information was getting dropped, but I am not sure that it was something that would arise in the normal protocol. IIRC it was something like 1. backend sends error in response to bogus user query; 2. backend encounters fatal problem during error cleanup (or gets shutdown signal from postmaster), and sends another errormessage to indicate this before it closes up shop. I think there may also be cases where we need to stuff both backend-generated messages and libpq-generated messages into the error result. That doesn't directly affect the protocol however. Since there will always be asynchronous conditions to deal with, it'd be pretty foolish to design a protocol that assumes that exactly one 'E' message will arrive during a PQexec cycle. > I am currently looking into extending the protocol so that more fields can > be in an ErrorResponse (e.g., error codes). If this were to happen then > we'd need a smarter way of handling more than one error message per cycle. Only if you want to overload ErrorResponse so that successive 'E' messages mean different things. I do not think that would be a good design. It'd be better to allow ErrorResponse to carry multiple fields. This'd imply a protocol version bump, but so what? Changing the semantics of ErrorResponse probably ought to require that anyway. (I have some other ideas that would require a protocol version bump too, like fixing the broken COPY and FastPath parts of the protocol...) regards, tom lane
Tom Lane writes: > Since there will always be asynchronous conditions to deal with, it'd > be pretty foolish to design a protocol that assumes that exactly one > 'E' message will arrive during a PQexec cycle. Reasonable. > > I am currently looking into extending the protocol so that more fields can > > be in an ErrorResponse (e.g., error codes). If this were to happen then > > we'd need a smarter way of handling more than one error message per cycle. > > Only if you want to overload ErrorResponse so that successive 'E' > messages mean different things. I do not think that would be a good > design. It'd be better to allow ErrorResponse to carry multiple fields. That's the idea. But I can hardly concatenate the error codes, can I? I looks as though we need an API where all the messages (errors + notices) from each query cycle are collected and can be cycled through after completion. > This'd imply a protocol version bump, but so what? Changing the > semantics of ErrorResponse probably ought to require that anyway. I think I could have done with a minor bump, but if you have some plans, too, the easier. -- Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
Peter Eisentraut <peter_e@gmx.net> writes: >> It'd be better to allow ErrorResponse to carry multiple fields. > That's the idea. But I can hardly concatenate the error codes, can I? I > looks as though we need an API where all the messages (errors + notices) > from each query cycle are collected and can be cycled through after > completion. One way to do this that wouldn't involve breaking the protocol is to assign significance to linebreaks in an 'E' message's payload. I think someone proposed this already: ERROR: blah blahCODE: 12345LOCATION: some/file.c line NNN ie, lines starting with agreed-on keywords would be taken as conveying specific fields. An arrangement like this could still work with plain concatenation of multiple errors. Also, it would work tolerably well when fed to an old application that knows nothing of the convention and just prints out the error string. I'm leery of defining a whole new API that must be used before one gets to see any of the added error information --- that would mean that a lot of people never will see it. regards, tom lane
Tom Lane writes: > One way to do this that wouldn't involve breaking the protocol is > to assign significance to linebreaks in an 'E' message's payload. Some fields may contain line breaks; for example, error messages definitely do now. We could pick a non-printing character (e.g., \001) as the separator, but it might get ugly with multibyte. Of course table names and such things can contain these characters as well, but I guess there wouldn't be so much resistance in changing that. At worst we could make up an escape mechanism. > Also, it would work tolerably well when fed to an old application that > knows nothing of the convention and just prints out the error string. > I'm leery of defining a whole new API that must be used before one > gets to see any of the added error information --- that would mean > that a lot of people never will see it. Okay, so PQerrorMessage will print the whole glob, whereas there would be an accessor method that would filter out the fields. That would also work transparently with the notice processor, which I was concerned about until now. I like it. -- Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
Peter Eisentraut <peter_e@gmx.net> writes: > Tom Lane writes: >> One way to do this that wouldn't involve breaking the protocol is >> to assign significance to linebreaks in an 'E' message's payload. > Some fields may contain line breaks; for example, error messages > definitely do now. Yes. I believe most of them are set up to indent the continuation lines, so there wouldn't be much of a problem interpreting the format. In any case, we could say that only a line beginning with a known keyword starts a new field. > Okay, so PQerrorMessage will print the whole glob, whereas there would be > an accessor method that would filter out the fields. That would also work > transparently with the notice processor, which I was concerned about until > now. I like it. Works for me. regards, tom lane
Tom Lane writes: > > Some fields may contain line breaks; for example, error messages > > definitely do now. > > Yes. I believe most of them are set up to indent the continuation > lines, so there wouldn't be much of a problem interpreting the format. This is not reliable. (Actually, it's not desirable either. Think about GUI or web applications or syslog: These formatting attempts are meaningless there. It'd be better to make error message mostly one-liners and worry about formatting in the front-ends. This is not a permanent workaround for the protocol problems, though.) > In any case, we could say that only a line beginning with a known > keyword starts a new field. That would probably require a protocol minor version bump anytime a keyword is added. A maintenance pain keeping both sides in sync. Also, I imagine that with the nature of data that parse tree dumps and other such debugging info (vacuum verbose?) throw out, it's possible to have misinterpretations -- or even malicious attacks -- with these scheme. [I wrote:] > > Okay, so PQerrorMessage will print the whole glob, whereas there would be > > an accessor method that would filter out the fields. I think there will a problem with programs that parse the error messages in lack of a better idea. Also, newlines are non-printing sometimes (see above), so this would produce a glob of garbage. I think an additional API is necessary. If you want extra information you need to ask for it. In fact, most of the additional information will be intended to be processed by a program, the error message text is the only thing humans need to see by default. -- Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter
Peter Eisentraut <peter_e@gmx.net> writes: > Tom Lane writes: > Some fields may contain line breaks; for example, error messages > definitely do now. >> >> Yes. I believe most of them are set up to indent the continuation >> lines, so there wouldn't be much of a problem interpreting the format. > This is not reliable. It could be made reliable if we wanted it to be. AFAIR, in all the places that currently emit error messages formatted like ERROR: something something else the "something else" is not really part of the error message anyway. It is explanatory material, a suggested workaround, or something like that. IMHO that ought to be treated as a secondary field of the error now that we're going to have secondary fields. Something like ERROR: Unable to identify an operator '!' for types 'int4' and 'int4'REMARK: You will have to retype this query using anexplicit cast > (Actually, it's not desirable either. Think about GUI or web applications > or syslog: These formatting attempts are meaningless there. It'd be > better to make error message mostly one-liners and worry about formatting > in the front-ends. I agree, but see above. > Also, I imagine that with the nature of data that parse tree dumps and > other such debugging info (vacuum verbose?) throw out, it's possible to > have misinterpretations -- or even malicious attacks -- with these scheme. I was not anticipating imposing any such structure on NOTICE messages. > [I wrote:] > Okay, so PQerrorMessage will print the whole glob, whereas there would be > an accessor method that would filter out the fields. I still think that is the right approach. The accessor methods would become the preferred way over time, but we shouldn't hide available information just because someone is using an old client. regards, tom lane