Creating a Custom Exception Handler in Java EE with NetBeans
A well-designed exception handler gives a Java EE application a predictable way to report failures. Instead of exposing stack traces or returning inconsistent error pages, the application can translate exceptions into clear HTTP responses, useful log entries and safe messages for clients.
NetBeans IDE makes this workflow straightforward because the project structure, REST resources, EJB services and deployment configuration can be inspected in one place. The example below uses JAX-RS, which is suitable for a Java EE web service serving browser applications, mobile clients or Australian business systems operating across Sydney, Melbourne and other regions.
Choosing The Exception Handling Boundary
First decide where the exception should be handled. An EJB service may throw a business exception such as AccountNotFoundException, while a REST endpoint should convert that exception into an HTTP status and a JSON response. Keeping these responsibilities separate prevents transport-specific code from spreading through the service layer.
A checked business exception is useful when the caller is expected to respond to a known condition. Runtime exceptions are better suited to programming errors or unexpected infrastructure failures. For example, an order service might reject an invalid delivery postcode with a business exception, while a database outage should be logged as an internal server failure without exposing database details.
Defining A Meaningful Exception Type
Create a package such as com.example.orders.exception in NetBeans, then add a custom exception class. A useful exception carries a stable message and, where appropriate, a code that can be recorded in logs or displayed by a client.
package com.example.orders.exception;
public class OrderNotFoundException extends Exception {
private final String orderId;
public OrderNotFoundException(String orderId) {
super("Order was not found");
this.orderId = orderId;
}
public String getOrderId() {
return orderId;
}
}
The public message deliberately avoids sensitive information. The order identifier can still be included in a server log, provided the application follows its privacy policy and the Australian Privacy Principles. A similar pattern works for payment failures, validation errors and unavailable inventory.
Mapping Exceptions To HTTP Responses
For a REST application, implement ExceptionMapper<T>. This JAX-RS provider receives the exception and builds a consistent response. In a Java EE 8 project, use javax.ws.rs imports; Jakarta EE projects use the equivalent jakarta.ws.rs packages.
package com.example.orders.rest;
import com.example.orders.exception.OrderNotFoundException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class OrderNotFoundMapper
implements ExceptionMapper<OrderNotFoundException> {
@Override
public Response toResponse(OrderNotFoundException exception) {
ErrorPayload payload = new ErrorPayload(
"ORDER_NOT_FOUND",
"The requested order could not be found"
);
return Response.status(Response.Status.NOT_FOUND)
.type(MediaType.APPLICATION_JSON)
.entity(payload)
.build();
}
}
The @Provider annotation allows the JAX-RS runtime to discover the mapper. The response should contain a stable error code and a client-safe description, rather than a Java class name or stack trace. A small ErrorPayload bean with getters is enough for JSON-B or another configured JSON provider to serialise the result.
Connecting The Handler In NetBeans
Create a REST resource that calls the service layer and allows the custom exception to propagate. The mapper will intercept it before it reaches the client.
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Order find(@PathParam("id") String id)
throws OrderNotFoundException {
return orderService.findById(id);
}
If the project uses an application subclass, register the provider explicitly when package scanning is disabled:
@ApplicationPath("/api")
public class RestApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
return new HashSet<>(Arrays.asList(
OrderResource.class,
OrderNotFoundMapper.class
));
}
}
Run the project from NetBeans using the configured GlassFish or Payara server and call /api/orders/123. A missing record should produce a 404 response with JSON. The IDE’s Services window can help verify the selected server, deployed application and endpoint URL.
Logging, Documentation And Tests
The mapper is a good place to record diagnostic information, but avoid logging the same exception at every layer. Log a concise event with a correlation identifier, exception class and relevant business context. For production services used across Australia, timestamps should be unambiguous, preferably in UTC, while user-facing displays can be converted to AEST, ACST or AWST where required.
Document the exception contract so frontend and integration teams know which status codes and error fields to expect. NetBeans can generate API documentation from source comments; the JavaDoc generation guide is useful when configuring that output. Include examples for invalid input, missing records and unexpected server failures.
Unit-test the mapper without starting a full application server. Assert the HTTP status, media type, error code and safe message. Then add an integration test that invokes the REST endpoint. A test suite should also verify that an unexpected NullPointerException becomes a generic 500 response rather than revealing implementation details.
When investigating complex failures, focused diagnostic tools can save time. For example, this discussion of regex backtracking hotspots illustrates how targeted analysis can expose expensive behaviour that may otherwise appear to be an ordinary timeout.
Practical Handler Design Recommendations
A custom exception strategy should remain consistent as the application grows. Australian retailers, banks and SaaS providers often integrate with several external systems, so a shared error format makes it easier to reconcile failures across payment gateways, delivery services and customer portals.
Keep exception classes small, map expected conditions explicitly and use a catch-all mapper only for genuinely unexpected failures. The following practices provide a sensible baseline:
- Return
400for malformed requests and404when a requested resource does not exist. - Use stable application error codes rather than asking clients to parse message text.
- Log stack traces on the server, never in a response intended for customers.
- Include a correlation ID so support teams can trace failures across services.
- Test JSON responses as well as status codes and content types.
- Keep business exceptions in the service layer and HTTP mapping in the REST layer.
This arrangement gives NetBeans developers a clear project structure, predictable API behaviour and safer diagnostics. It also leaves room to add handlers for validation exceptions, authentication failures and downstream service timeouts without changing every REST resource.