Recently I wrote a detailed post on these and some related questions.
Should I return a status code and a message in a response?
Yes, but message should not contain exception message unless that message was crafted specifically to be shown to end user. Since you talk about DomainException
, which probably should be quite specific about explaining what happened and why, you may show this exception message to a user. However, I recommend you to separate domain-level exceptions from API-level exceptions, and make latter be 100% "user-safe", so you can show them to end user without worrying it contains something like "MySQLIntegrityConstraintViolationException".
API-level exceptions should look like this:
// Assume that all those exception classes extend some base class `ApiException`
throw new ApiNotFoundException(404, "Entity with id=" + id + " not found.");
throw new ApiDatabaseUnavailableException(502, "Database server is unavailable. Retry later.")
throw new ApiConstraintViolationException(422, // WebDAV, Unprocessable Entity
"Entity with id=" + id + " cannot be deleted " +
"because it is a parent of entity with id=" + childId + ". "
"Delete all children first.");
Where should it be detected and how?
There are several layers in application where different types of exceptions whould be handled. Basic idea is: handle standard Java exceptions (NPEs, IllegalArgument, etc.) as soon as possible, wrap them into something more specific and throw further. Then later you can handle domain-specific exception in a middle layer, and finally API-specific exceptions can all be handled in a single "catch-them-all" handler/interceptor.
See Logging Exceptions: Where to Log Exceptions? and my post for details.
And since it's not a checked exception, how should I handle it? Try/Catch for a runtime exception seems to be awful.
try
/catch
is just fine if you catch exceptions at the right level. The main mistake I see people make (which initially made me write about it) is catching exceptions too far up in the call stack from the place they've been thrown - basically, too "late". In such cases people try to guess what happened by examining exception type and/or pattern-matching a message. That was indeed horrible when I saw NPE was interpreted as "item not found in the database" (it actually was just random null
somewhere in between).
Maybe if we're talking about specifing implementation, should I use something like spring's @ExceptionHandler
?
You should use that kind of things as well, but only for API/domain-level exceptions.