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:

Previous
From: Fernando Nasser
Date:
Subject: JDBC Emit SQLError code for communication errors
Next
From: Barry Lind
Date:
Subject: Re: JDBC Emit SQLError code for communication errors