Knowing your exception class name

You’re staring at a generic catch (Exception e) and you don’t know which actual exception is being thrown. The trick is to log the runtime class so you can replace the generic catch with a specific one:

1
2
3
4
5
} catch (Exception e) {
    LOG.error("SQL error when processing " + requestId
        + ". Exception class: " + e.getClass().getCanonicalName());
    throw e;
}

Run the failing scenario, read the log, and you’ll see something like java.sql.SQLIntegrityConstraintViolationException — now you can write a specific catch for it.


A few useful additions.

Three flavours of class name. The Class object exposes three different name accessors and they behave differently for inner / anonymous classes:

  • getName() — JVM internal name. Inner classes show up with a dollar sign: com.acme.Outer$Inner.
  • getCanonicalName() — Java source-style name. Inner classes use a dot: com.acme.Outer.Inner. Returns null for anonymous and local classes.
  • getSimpleName() — just the leaf name, no package: Inner. Empty string for anonymous classes.

For diagnostics, getName() is usually safest because it never returns null. getCanonicalName() reads more naturally in logs but bites you the moment an exception comes from an anonymous class.

If you’re using SLF4J, you don’t need to format the exception yourself. Pass the throwable as the last argument and SLF4J logs the class name and the full stack trace for free:

1
2
3
4
} catch (Exception e) {
    LOG.error("SQL error when processing {}", requestId, e);
    throw e;
}

That single line gives you more diagnostic information than the original — no manual getClass() call needed.

Once you know the class, prefer multi-catch over a generic catch (Exception). Java 7+ supports listing several exception types in one block:

1
2
3
4
} catch (SQLIntegrityConstraintViolationException | DataAccessException e) {
    LOG.error("SQL error when processing {}", requestId, e);
    throw e;
}

This narrows what you’re handling, makes the intent obvious to readers, and lets your linter actually help you. The original “log the class name” trick is a great discovery tool — but once you’ve discovered, replace it with a specific catch. 🪲

This entry was posted in java and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


+ 6 = seven