Extra Fields in Custom Exception Classes
Fast recall
Quick revision
Core answer
errorCode, the offending resourceId, a list of validation failures. Expose them via getters and set them in the constructor. Don't add fields that just duplicate the message, and keep the exception otherwise logic-free. Structured fields let a global handler build precise API responses.Whether you know when extra fields add value (structured context) versus clutter (duplicating the message)
Either never adding useful context, or stuffing mutable state and logic into exceptions
Show how an errorCode or field list lets a @RestControllerAdvice build a precise, machine-readable error response
Interview-ready guide
Interview answer
Yes, adding fields to a custom exception is good practice, but only when those fields carry structured context that code can actually use, as opposed to just decorating the message.
Good examples are an error code that a client can branch on, the id of the resource that wasn't found, or a list of field-level validation errors. The idea is that the message string is for humans to read in a log, but these fields are for machines — they let a handler do something precise programmatically.
The way you do it is to set the fields in the constructor, pass a human-readable message up to super, and then expose the fields through getters. You want them effectively immutable, so make them final and don't add setters — an exception that's been thrown shouldn't be mutated. The big payoff shows up in something like a Spring at RestControllerAdvice handler.
If your ResourceNotFoundException carries the resource type and id as fields, the handler can build a clean, machine-readable JSON error body directly from those getters, instead of trying to parse information back out of the message string, which is fragile.
What you should avoid is adding fields that just restate what's already in the message, because that's noise, and you should definitely not put mutable state or business logic into the exception — it's a data carrier describing a failure, not a service. And don't forget to still pass a proper message to super, so you keep that human-readable summary in your logs alongside the structured fields.
So the short answer is: add fields when they give you actionable, structured context, keep them immutable with getters, and otherwise keep the exception simple.
Extra Fields in Custom Exception Classes
Direct Answer
Yes — add fields when they carry structured, machine-usable context the message string can't: an errorCode, the offending resourceId, a list of validation failures. Expose them via getters and set them in the constructor. Don't add fields that just duplicate the message, and keep the exception otherwise logic-free. Structured fields let a global handler build precise API responses.
Deep Dive & Architecture
A custom exception may carry stable data that callers need separately from its human-readable message. Useful fields include an error code, a resource identifier, or validation failures. Set them in the constructor, expose read-only accessors, and still pass the message and optional cause to the superclass.
For example, OrderNotFoundException can contain orderId, allowing a global HTTP handler to build a consistent error body without parsing text. The message can then change for clarity without breaking code. Avoid copying the same sentence into several fields, putting business logic in the exception, or storing secrets and large mutable objects. Fields should describe the failure, not turn the exception into a general data container.
Code Example
public class ResourceNotFoundException extends RuntimeException {
private final String resourceType; // structured context
private final Object resourceId;
public ResourceNotFoundException(String resourceType, Object resourceId) {
super(resourceType + " not found: " + resourceId); // human message
this.resourceType = resourceType;
this.resourceId = resourceId;
}
public String getResourceType() { return resourceType; }
public Object getResourceId() { return resourceId; }
}
// A handler can now build a precise response without parsing the message:
// new ApiError("NOT_FOUND", e.getResourceType(), e.getResourceId())
Fields carry machine-usable context; the super(...) message stays the human-readable summary.
Common Mistakes & Pitfalls
- Fields that duplicate the message — adds noise without new information.
- Mutable fields / setters — exceptions should be effectively immutable.
- Business logic in the exception — it's a data carrier, not a service.
- Forgetting to still pass a message to
super— you lose the human-readable summary.
Check your understanding
Answer these without looking back at the article.
- How do you create a custom exception in Java?
- Why is it important to add a cause constructor to a custom exception?
- How would you design exceptions for a layered Spring application?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.