public static StandardException unexpectedUserException(Throwable t)
{
// If the exception is an SQLException generated by Derby, it has an
// argument ferry which is an EmbedSQLException. Use this to check
// whether the exception was generated by Derby.
EmbedSQLException ferry = null;
if (t instanceof SQLException) {
SQLException sqle =
Util.getExceptionFactory().getArgumentFerry((SQLException) t);
if (sqle instanceof EmbedSQLException) {
ferry = (EmbedSQLException) sqle;
}
}
/*
** If we have a SQLException that isn't an EmbedSQLException
** (i.e. it didn't come from Derby), then we check
** to see if it is a valid user defined exception range
** (38001-38XXX). If so, then we convert it into a
** StandardException without further ado.
*/
if ((t instanceof SQLException) && (ferry == null))
{
SQLException sqlex = (SQLException)t;
String state = sqlex.getSQLState();
if ((state != null) &&
(state.length() == 5) &&
state.startsWith("38") &&
!state.equals("38000"))
{
StandardException se = new StandardException(state, sqlex.getMessage());
if (sqlex.getNextException() != null)
{
se.initCause(sqlex.getNextException());
}
return se;
}
}
// Look for simple wrappers for 3.0.1 - will be cleaned up in main
if (ferry != null) {
if (ferry.isSimpleWrapper()) {
Throwable wrapped = ferry.getCause();
if (wrapped instanceof StandardException)
return (StandardException) wrapped;
}
}
// no need to wrap a StandardException
if (t instanceof StandardException)
{
return (StandardException) t;
}
else
{
/*
**
** The exception at this point could be a:
**
** standard java exception, e.g. NullPointerException
** SQL Exception - from some server-side JDBC
** 3rd party exception - from some application
** some Derby exception that is not a standard exception.
**
**
** We don't want to call t.toString() here, because the JVM is
** inconsistent about whether it includes a detail message
** with some exceptions (esp. NullPointerException). In those
** cases where there is a detail message, t.toString() puts in
** a colon character, even when the detail message is blank.
** So, we do our own string formatting here, including the colon
** only when there is a non-blank message.
**
** The above is because our test canons contain the text of
** error messages.
**
** In the past we didn't want to place the class name in
** an exception because Cloudscape builds were
** obfuscated, so the class name would change from build
** to build. This is no longer true for Derby, but for
** exceptions that are Derby's, i.e. EmbedSQLException,
** we use toString(). If this returns an empty or null
** then we use the class name to make tracking the
** problem down easier, though the lack of a message
** should be seen as a bug.
*/
String detailMessage;
boolean derbyException = false;
if (ferry != null) {
detailMessage = ferry.toString();
derbyException = true;
}
else {
detailMessage = t.getMessage();
}