Re: JDBC Emit SQLError code for communication errors - Mailing list pgsql-patches
From | Fernando Nasser |
---|---|
Subject | Re: JDBC Emit SQLError code for communication errors |
Date | |
Msg-id | 3DDAE658.5070302@redhat.com Whole thread Raw |
In response to | JDBC Emit SQLError code for communication errors (Fernando Nasser <fnasser@redhat.com>) |
List | pgsql-patches |
Please consider this version of the patch. The extra cases (postgresql.stream.ioerror:An I/O error occurred while reading from backend) also should result in "08S01"s. I left postgresql.updateable.ioerror:Input Stream Error as the "08S01" does not seem completely appropriate for those. Regards, Fernando Fernando Nasser wrote: > Applications can't rely on the text of the SQLException error message to > detect that there was a communication error as it is localized (and > error messages are prone to change anyway). So, a JDBC application > cannot take the appropriate actions when an IO error occurs. > > This patch makes the JDBC driver report an eof and other communication > errors using the standard SQLSTATE value: > > "08S01" (connection exception-communication link failure) > > which can be safely tested for in applications. Without this patch we > get null, instead of the "08S01" string, when calling getSQLState() as > the driver never sets that value. > > The behavior of applications when we lose connection with the backend is > currently very bad, as there is no way to distinguish this problem from > a regular SQL error. > > > ------------------------------------------------------------------------ > > Index: src/interfaces/jdbc/org/postgresql/PG_Stream.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/PG_Stream.java,v > retrieving revision 1.17 > diff -c -p -r1.17 PG_Stream.java > *** src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/08/20 04:26:02 1.17 > --- src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/11/19 22:21:33 > *************** public class PG_Stream > *** 137,143 **** > { > c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof"); > } > catch (IOException e) > { > --- 137,143 ---- > { > c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof", "08S01"); > } > catch (IOException e) > { > *************** public class PG_Stream > *** 164,170 **** > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof"); > n = n | (b << (8 * i)) ; > } > } > --- 164,170 ---- > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof", "08S01"); > n = n | (b << (8 * i)) ; > } > } > *************** public class PG_Stream > *** 193,199 **** > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof"); > n = b | (n << 8); > } > } > --- 193,199 ---- > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof", "08S01"); > n = b | (n << 8); > } > } > *************** public class PG_Stream > *** 227,233 **** > { > int c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof"); > else if (c == 0) > { > rst[s] = 0; > --- 227,233 ---- > { > int c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof", "08S01"); > else if (c == 0) > { > rst[s] = 0; > *************** public class PG_Stream > *** 330,336 **** > { > int w = pg_input.read(b, off + s, siz - s); > if (w < 0) > ! throw new PSQLException("postgresql.stream.eof"); > s += w; > } > } > --- 330,336 ---- > { > int w = pg_input.read(b, off + s, siz - s); > if (w < 0) > ! throw new PSQLException("postgresql.stream.eof", "08S01"); > s += w; > } > } > Index: src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java,v > retrieving revision 1.17 > diff -c -p -r1.17 QueryExecutor.java > *** src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/14 05:35:45 1.17 > --- src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/19 22:21:33 > *************** public class QueryExecutor > *** 156,162 **** > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.ioerror", e); > } > } > > --- 156,162 ---- > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.ioerror", "08S01", e); > } > } > > Index: src/interfaces/jdbc/org/postgresql/util/PSQLException.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/PSQLException.java,v > retrieving revision 1.7 > diff -c -p -r1.7 PSQLException.java > *** src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2001/11/19 22:33:39 1.7 > --- src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2002/11/19 22:21:33 > *************** public class PSQLException extends SQLEx > *** 21,26 **** > --- 21,37 ---- > } > > /* > + * Like the above, but sets SQLState > + * @param error Error string > + * @param sqlstate SQLState string > + */ > + public PSQLException(String error, String sqlstate) > + { > + super("", sqlstate); > + translate(error, null); > + } > + > + /* > * A more generic entry point. > * @param error Error string or standard message id > * @param args Array of arguments > *************** public class PSQLException extends SQLEx > *** 50,55 **** > --- 61,95 ---- > public PSQLException(String error, Exception ex) > { > super(); > + > + Object[] argv = new Object[1]; > + > + try > + { > + ByteArrayOutputStream baos = new ByteArrayOutputStream(); > + PrintWriter pw = new PrintWriter(baos); > + pw.println("Exception: " + ex.toString() + "\nStack Trace:\n"); > + ex.printStackTrace(pw); > + pw.println("End of Stack Trace"); > + pw.flush(); > + argv[0] = baos.toString(); > + pw.close(); > + baos.close(); > + } > + catch (Exception ioe) > + { > + argv[0] = ex.toString() + "\nIO Error on stack trace generation! " + ioe.toString(); > + } > + > + translate(error, argv); > + } > + > + /* > + * Like the above, but sets the SQLState > + */ > + public PSQLException(String error, String sqlstate, Exception ex) > + { > + super("", sqlstate); > > Object[] argv = new Object[1]; > > > > ------------------------------------------------------------------------ > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org -- Fernando Nasser Red Hat Canada Ltd. E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9 Index: src/interfaces/jdbc/org/postgresql/PG_Stream.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/PG_Stream.java,v retrieving revision 1.17 diff -c -p -r1.17 PG_Stream.java *** src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/08/20 04:26:02 1.17 --- src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/11/20 01:20:16 *************** public class PG_Stream *** 137,147 **** { c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof"); } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return c; } --- 137,147 ---- { c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof", "08S01"); } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", "08S01", e); } return c; } *************** public class PG_Stream *** 164,176 **** int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof"); n = n | (b << (8 * i)) ; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return n; } --- 164,176 ---- int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof", "08S01"); n = n | (b << (8 * i)) ; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", "08S01", e); } return n; } *************** public class PG_Stream *** 193,205 **** int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof"); n = b | (n << 8); } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return n; } --- 193,205 ---- int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof", "08S01"); n = b | (n << 8); } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", "08S01", e); } return n; } *************** public class PG_Stream *** 227,233 **** { int c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof"); else if (c == 0) { rst[s] = 0; --- 227,233 ---- { int c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof", "08S01"); else if (c == 0) { rst[s] = 0; *************** public class PG_Stream *** 250,256 **** } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return encoding.decode(rst, 0, s); } --- 250,256 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", "08S01", e); } return encoding.decode(rst, 0, s); } *************** public class PG_Stream *** 330,342 **** { int w = pg_input.read(b, off + s, siz - s); if (w < 0) ! throw new PSQLException("postgresql.stream.eof"); s += w; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } } --- 330,342 ---- { int w = pg_input.read(b, off + s, siz - s); if (w < 0) ! throw new PSQLException("postgresql.stream.eof", "08S01"); s += w; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", "08S01", e); } } Index: src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java,v retrieving revision 1.17 diff -c -p -r1.17 QueryExecutor.java *** src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/14 05:35:45 1.17 --- src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/20 01:20:16 *************** public class QueryExecutor *** 156,162 **** } catch (IOException e) { ! throw new PSQLException("postgresql.con.ioerror", e); } } --- 156,162 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.con.ioerror", "08S01", e); } } Index: src/interfaces/jdbc/org/postgresql/util/PSQLException.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/PSQLException.java,v retrieving revision 1.7 diff -c -p -r1.7 PSQLException.java *** src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2001/11/19 22:33:39 1.7 --- src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2002/11/20 01:20:16 *************** public class PSQLException extends SQLEx *** 21,26 **** --- 21,37 ---- } /* + * Like the above, but sets SQLState + * @param error Error string + * @param sqlstate SQLState string + */ + public PSQLException(String error, String sqlstate) + { + super("", sqlstate); + translate(error, null); + } + + /* * A more generic entry point. * @param error Error string or standard message id * @param args Array of arguments *************** public class PSQLException extends SQLEx *** 50,55 **** --- 61,95 ---- public PSQLException(String error, Exception ex) { super(); + + Object[] argv = new Object[1]; + + try + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(baos); + pw.println("Exception: " + ex.toString() + "\nStack Trace:\n"); + ex.printStackTrace(pw); + pw.println("End of Stack Trace"); + pw.flush(); + argv[0] = baos.toString(); + pw.close(); + baos.close(); + } + catch (Exception ioe) + { + argv[0] = ex.toString() + "\nIO Error on stack trace generation! " + ioe.toString(); + } + + translate(error, argv); + } + + /* + * Like the above, but sets the SQLState + */ + public PSQLException(String error, String sqlstate, Exception ex) + { + super("", sqlstate); Object[] argv = new Object[1];
pgsql-patches by date: