Here are various ways to tackle this problem:
1) We could create a parallel universe of SQLException subclasses, which extend the JDBC4 SQLException subclasses and implement some vacuous, Derby-specific interface. These would be the exceptions raised by SQLExceptionFactory40. EmbedSQLException could implement this vacuous interface too. In the code above (StandardException.unexpectedUserException()), we could then check whether the exception class was an instance of the vacuous interface.
+ I think this covers the cases
- Bloats up the server with around 20 new classes
- As more SQLException subclasses are added to JDBC, we will have to add additional parallel Derby classes
2) We could check whether the errorCode was one of the Derby-specific severities. This would be our flag that the exception was generated by Derby.
+ Not a lot of code bloat.
- Has wormholes: What if the user-created exception uses one of our severities as its error code?
3) We could check whether the passed-in SQLException's getCause() method returns an EmbedSQLException. This would be true for all exceptions created by SQLExceptionFactory40
+ Also not a lot of code bloat
- Still has the wormhole that the user-created exception could set a Derby exception as its cause