001: /*
002:
003: Derby - Class org.apache.derby.client.am.ExceptionFormatter
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021: package org.apache.derby.client.am;
022:
023: public class ExceptionFormatter {
024: // returnTokensOnly is true only when exception tracing is enabled so
025: // that we don't try to go to the server for a message while we're in
026: // the middle of parsing an Sqlca reply.
027: // Without this, if e.getMessage() fails, we would have infinite recursion
028: // when TRACE_DIAGNOSTICS is on because tracing occurs within the exception constructor.
029: static public void printTrace(SqlException e,
030: java.io.PrintWriter printWriter, String messageHeader,
031: boolean returnTokensOnly) {
032: String header;
033: synchronized (printWriter) {
034: while (e != null) {
035: header = messageHeader + "[" + "SQLException@"
036: + Integer.toHexString(e.hashCode()) + "]";
037: printWriter.println(header + " java.sql.SQLException");
038:
039: java.lang.Throwable throwable = null;
040: try {
041: throwable = ((Diagnosable) e).getThrowable();
042: } catch (java.lang.NoSuchMethodError doNothing) {
043: }
044: if (throwable != null) {
045: printTrace(throwable, printWriter, header);
046: }
047: Sqlca sqlca = ((Diagnosable) e).getSqlca();
048: if (sqlca != null) {
049: printTrace(sqlca, printWriter, header);
050: // JDK stack trace calls e.getMessage(), so we must set some state on the sqlca that says return tokens only.
051: ((Sqlca) sqlca)
052: .returnTokensOnlyInMessageText(returnTokensOnly);
053: }
054:
055: printWriter.println(header + " SQL state = "
056: + e.getSQLState());
057: printWriter.println(header + " Error code = "
058: + String.valueOf(e.getErrorCode()));
059: if (((Diagnosable) e).getSqlca() == null) { // Too much has changed, so escape out here.
060: printWriter.println(header + " Message = "
061: + e.getMessage());
062: } else { // This is server-side error.
063: sqlca = ((Diagnosable) e).getSqlca();
064: if (returnTokensOnly) {
065: // print message tokens directly.
066: printWriter.println(header + " Tokens = "
067: + sqlca.getSqlErrmc()); // a string containing error tokens only
068: } else {
069: // Try to get message text from server.
070: String message = e.getMessage();
071: if (!sqlca.messageTextRetrievedContainsTokensOnly_) { // got the message text.
072: printWriter.println(header
073: + " Message = " + message);
074: } else { // got only message tokens.
075: SqlException mysteryException = sqlca.exceptionThrownOnStoredProcInvocation_;
076: if (mysteryException != null
077: && (mysteryException.getErrorCode() == -440 || mysteryException
078: .getErrorCode() == -444)) {
079: printWriter
080: .println(header
081: + " Unable to obtain message text from server."
082: + " Only message tokens are available."
083: + " The stored procedure SYSIBM.SQLCAMESSAGE is not installed on server."
084: + " Contact your DBA.");
085: } else {
086: printWriter
087: .println(header
088: + " Error occurred while trying to obtain message text from server. "
089: + "Only message tokens are available.");
090: }
091: printWriter.println(header
092: + " Tokens = " + message);
093: }
094: }
095: }
096:
097: printWriter.println(header + " Stack trace follows");
098: e.printStackTrace(printWriter);
099:
100: if (e instanceof Diagnosable) {
101: sqlca = (Sqlca) ((Diagnosable) e).getSqlca();
102: if (sqlca != null) {
103: // JDK stack trace calls e.getMessage(), now that it is finished,
104: // we can reset the state on the sqlca that says return tokens only.
105: sqlca.returnTokensOnlyInMessageText(false);
106: }
107: }
108:
109: e = e.getNextException();
110: }
111:
112: printWriter.flush();
113: }
114: }
115:
116: static public void printTrace(java.sql.SQLException e,
117: java.io.PrintWriter printWriter, String messageHeader,
118: boolean returnTokensOnly) {
119: String header;
120: synchronized (printWriter) {
121: while (e != null) {
122: if (e instanceof java.sql.DataTruncation) {
123: header = messageHeader + "[" + "DataTruncation@"
124: + Integer.toHexString(e.hashCode()) + "]";
125: printWriter.println(header
126: + " java.sql.DataTruncation");
127: } else if (e instanceof java.sql.SQLWarning) {
128: header = messageHeader + "[" + "SQLWarning@"
129: + Integer.toHexString(e.hashCode()) + "]";
130: printWriter
131: .println(header + " java.sql.SQLWarning");
132: } else if (e instanceof java.sql.BatchUpdateException) {
133: header = messageHeader + "["
134: + "BatchUpdateException@"
135: + Integer.toHexString(e.hashCode()) + "]";
136: printWriter.println(header
137: + " java.sql.BatchUpdateException");
138: } else { // e instanceof java.sql.SQLException
139: header = messageHeader + "[" + "SQLException@"
140: + Integer.toHexString(e.hashCode()) + "]";
141: printWriter.println(header
142: + " java.sql.SQLException");
143: }
144:
145: printWriter.println(header + " SQL state = "
146: + e.getSQLState());
147: printWriter.println(header + " Error code = "
148: + String.valueOf(e.getErrorCode()));
149: printWriter.println(header + " Message = "
150: + e.getMessage());
151:
152: if (e instanceof java.sql.DataTruncation) {
153: printWriter.println(header + " Index = "
154: + ((java.sql.DataTruncation) e).getIndex());
155: printWriter.println(header
156: + " Parameter = "
157: + ((java.sql.DataTruncation) e)
158: .getParameter());
159: printWriter.println(header + " Read = "
160: + ((java.sql.DataTruncation) e).getRead());
161: printWriter.println(header
162: + " Data size = "
163: + ((java.sql.DataTruncation) e)
164: .getDataSize());
165: printWriter.println(header
166: + " Transfer size = "
167: + ((java.sql.DataTruncation) e)
168: .getTransferSize());
169: }
170:
171: if (e instanceof java.sql.BatchUpdateException) {
172: printWriter
173: .println(header
174: + " Update counts = "
175: + Utils
176: .getStringFromInts(((java.sql.BatchUpdateException) e)
177: .getUpdateCounts()));
178: }
179:
180: printWriter.println(header + " Stack trace follows");
181: e.printStackTrace(printWriter);
182:
183: e = e.getNextException();
184: }
185:
186: printWriter.flush();
187: }
188: }
189:
190: static public void printTrace(Sqlca sqlca,
191: java.io.PrintWriter printWriter, String messageHeader) {
192: String header = messageHeader + "[" + "Sqlca@"
193: + Integer.toHexString(sqlca.hashCode()) + "]";
194: synchronized (printWriter) {
195: printWriter.println(header + " DERBY SQLCA from server");
196: printWriter.println(header + " SqlCode = "
197: + sqlca.getSqlCode());
198: printWriter.println(header + " SqlErrd = "
199: + Utils.getStringFromInts(sqlca.getSqlErrd()));
200: printWriter.println(header + " SqlErrmc = "
201: + sqlca.getSqlErrmc());
202: printWriter.println(header
203: + " SqlErrmcTokens = "
204: + Utils.getStringFromStrings(sqlca
205: .getSqlErrmcTokens()));
206: printWriter.println(header + " SqlErrp = "
207: + sqlca.getSqlErrp());
208: printWriter.println(header + " SqlState = "
209: + sqlca.getSqlState());
210: printWriter.println(header + " SqlWarn = "
211: + new String(sqlca.getSqlWarn()));
212: }
213: }
214:
215: static public void printTrace(java.lang.Throwable e,
216: java.io.PrintWriter printWriter, String messageHeader) {
217: String header = messageHeader + "[" + "Throwable@"
218: + Integer.toHexString(e.hashCode()) + "]";
219: synchronized (printWriter) {
220: printWriter.println(header + " " + e.getClass().getName());
221: printWriter
222: .println(header + " Message = " + e.getMessage());
223: printWriter.println(header + " Stack trace follows");
224: e.printStackTrace(printWriter);
225: }
226: }
227:
228: static public void printTrace(javax.transaction.xa.XAException e,
229: java.io.PrintWriter printWriter, String messageHeader) {
230: String header = messageHeader + "[" + "XAException@"
231: + Integer.toHexString(e.hashCode()) + "]";
232: synchronized (printWriter) {
233: printWriter.println(header
234: + " javax.transaction.xa.XAException");
235: printWriter
236: .println(header + " Message = " + e.getMessage());
237: printWriter.println(header + " Stack trace follows");
238:
239: e.printStackTrace(printWriter);
240:
241: if (!((org.apache.derby.client.am.Configuration.jreLevelMajor == 1) && (org.apache.derby.client.am.Configuration.jreLevelMinor >= 4))
242: || (org.apache.derby.client.am.Configuration.jreLevelMajor > 1)) { // If not jre 1.4 or above, we need to print the cause if there is one
243: // For jre 1.4 or above, e.printStackTrace() will print the cause automatically
244: if (e instanceof Diagnosable) {
245: java.lang.Throwable throwable = null;
246: try {
247: throwable = ((Diagnosable) e).getThrowable();
248: } catch (java.lang.NoSuchMethodError doNothing) {
249: }
250: if (throwable != null) {
251: printWriter.print("Caused by: ");
252: if (throwable instanceof java.sql.SQLException) {
253: throwable.printStackTrace(printWriter);
254: } else {
255: printTrace(throwable, printWriter, header);
256: }
257: }
258: }
259: }
260: }
261: }
262: }
|