A user-defined exception gives a failure an intention-revealing name. Translate low-level failures into a domain exception or controlled response at a business, API, or user-facing boundary; keep technical detail in logs. section 7.2.4
Make the exception carry the information known when it is created, and keep that state immutable. An apparently small class can make the code’s failure story clearer than a generic exception. section 7.2.4
Wrap parsing without losing the cause
When parsing input fails, throw DataProcessingException with the original data, a meaningful message, and the caught NumberFormatException as its cause. The caller sees a domain-level failure while diagnostics retain the root cause. section 7.2.4
int dataToTransform = 0;
try {
dataToTransform = Integer.parseInt(data);
} catch (NumberFormatException exception) {
throw new DataProcessingException(data, "Processing error", exception);
}
This listing turns a NumberFormatException into a named data-processing failure while preserving the original exception. section 7.2.4
Do not replace an original error without preserving it. Otherwise logs can report only that processing failed, obscuring whether the cause was a missing file, permissions, malformed input, or another technical problem. section 7.2.4


