public static void printTrace( Sqlca sqlca, java.io.PrintWriter printWriter, String messageHeader) { String header = messageHeader + "[" + "Sqlca@" + Integer.toHexString(sqlca.hashCode()) + "]"; synchronized (printWriter) { printWriter.println(header + " DERBY SQLCA from server"); printWriter.println(header + " SqlCode = " + sqlca.getSqlCode()); printWriter.println( header + " SqlErrd = " + Utils.getStringFromInts(sqlca.getSqlErrd())); printWriter.println(header + " SqlErrmc = " + sqlca.getSqlErrmc()); printWriter.println(header + " SqlErrp = " + sqlca.getSqlErrp()); printWriter.println(header + " SqlState = " + sqlca.getSqlState()); printWriter.println(header + " SqlWarn = " + new String(sqlca.getSqlWarn())); } }
// returnTokensOnly is true only when exception tracing is enabled so // that we don't try to go to the server for a message while we're in // the middle of parsing an Sqlca reply. // Without this, if e.getMessage() fails, we would have infinite recursion // when TRACE_DIAGNOSTICS is on because tracing occurs within the exception constructor. public static void printTrace( SqlException e, java.io.PrintWriter printWriter, String messageHeader, boolean returnTokensOnly) { String header; synchronized (printWriter) { while (e != null) { header = messageHeader + "[" + "SQLException@" + Integer.toHexString(e.hashCode()) + "]"; printWriter.println(header + " java.sql.SQLException"); java.lang.Throwable throwable = e.getCause(); if (throwable != null) { printTrace(throwable, printWriter, header); } Sqlca sqlca = ((Diagnosable) e).getSqlca(); if (sqlca != null) { printTrace(sqlca, printWriter, header); // JDK stack trace calls e.getMessage(), so we must set some state on the sqlca that says // return tokens only. ((Sqlca) sqlca).returnTokensOnlyInMessageText(returnTokensOnly); } printWriter.println(header + " SQL state = " + e.getSQLState()); printWriter.println(header + " Error code = " + String.valueOf(e.getErrorCode())); if (((Diagnosable) e).getSqlca() == null) { // Too much has changed, so escape out here. printWriter.println(header + " Message = " + e.getMessage()); } else { // This is server-side error. sqlca = ((Diagnosable) e).getSqlca(); if (returnTokensOnly) { // print message tokens directly. printWriter.println( header + " Tokens = " + sqlca.getSqlErrmc()); // a string containing error tokens only } else { // Try to get message text from server. String message = e.getMessage(); if (!sqlca.messageTextRetrievedContainsTokensOnly_) { // got the message text. printWriter.println(header + " Message = " + message); } else { // got only message tokens. SqlException mysteryException = sqlca.exceptionThrownOnStoredProcInvocation_; if (mysteryException != null && (mysteryException.getErrorCode() == -440 || mysteryException.getErrorCode() == -444)) { printWriter.println( header + " Unable to obtain message text from server." + " Only message tokens are available." + " The stored procedure SYSIBM.SQLCAMESSAGE is not installed on server." + " Contact your DBA."); } else { printWriter.println( header + " Error occurred while trying to obtain message text from server. " + "Only message tokens are available."); } printWriter.println(header + " Tokens = " + message); } } } printWriter.println(header + " Stack trace follows"); e.printStackTrace(printWriter); if (e instanceof Diagnosable) { sqlca = (Sqlca) ((Diagnosable) e).getSqlca(); if (sqlca != null) { // JDK stack trace calls e.getMessage(), now that it is finished, // we can reset the state on the sqlca that says return tokens only. sqlca.returnTokensOnlyInMessageText(false); } } e = e.getNextException(); } printWriter.flush(); } }