Logo

dev-resources.site

for different kinds of informations.

Effective Java: Include Failure-Capture Information in Detail Messages

Published at
9/29/2021
Categories
java
effective
exceptions
architecture
Author
kylec32
Author
7 person written this
kylec32
open
Effective Java: Include Failure-Capture Information in Detail Messages

Often when we are analyzing a failure of some code all we are left with is the logs that are left behind. Seeing as this is the case, we want to give ourselves the best chance of success. When a program fails the system will automatically output the exception's stack trace which includes the value that gets returned from the toString method of the exception. This message serves as a core capability in explaining the state of the system and particularly the exception to the future investigators. Because of this, we should do our best to include any relevant information to understand why the system failed.

An example that Effective Java provides is the example of a IndexOutOfBoundsException. Thinking through what information could be useful when analyzing such a failure some of the things that could be useful are the lower bound, upper bound, and index specified. Through having these pieces of information we can get some solid insight into the state at the time of the failure. One exception to this is with security-sensitive information. Because log visibility can often be fairly far-reaching we should keep all passwords, encryption keys, and other security-sensitive information out of the logs and thus out of the exception messages of our code.

When writing the toString method we should focus on providing details rather than lots of prose. The audience for logs messages are developers and other engineers working on the system. Because of this, these people already have access to the source code and documentation and thus the focus shouldn't be on that and more on the current state. Put another way, focus your messages on what changes, not on what is the same.

The best way to ensure this critical information gets provided when the exception is thrown is to require the pertinent information in the constructor. By doing this it ensures that the data will be provided. This also allows the caller of the exception to not need to know how to write the detailed toString messages. As an example of what this could look like in our IndexOutOfBoundsException example let us consider the following code:

public IndexOutOfBoundsException(int lowerBound, int higherBound, int index) {
  super(String.format("Lower bound %d, Upper bound %d, Index: %d", lowerBound, higherBound, index));

  this.lowerBound = lowerBound;
  this.higherBound = higherBound;
  this.index = index;
}
Enter fullscreen mode Exit fullscreen mode

Another item to note in this example is that the variables are saved off in the exception object thus they are able to be pulled out by any code that catches these exceptions.

By providing useful detailed messages in exceptions we can speed up the dispositioning and recovery from exceptions. As often is the case, considering simple things at the beginning of a project can pay off big when operating a service.

effective Article's
30 articles in total
Favicon
What is The Best Time to Learn New Things Effectively?
Favicon
Designing an Efficient Biomass Generator Set System
Favicon
Top 10 Essential Features for an Effective Knowledge Base
Favicon
Effective Java: Consider Serialization Proxies Instead of Serialized Instances
Favicon
Effective Java: For Instance Control, Prefer Enum types to readResolve
Favicon
Effective Java: Write readObject Methods Defensively
Favicon
Effective Java: Consider Using a Custom Serialized Form
Favicon
Effective Java: Implement Serializable With Great Caution
Favicon
Effective Java: Prefer Alternatives To Java Serialization
Favicon
Effective Java: Don't Depend on the Thread Scheduler
Favicon
Effective Java: Use Lazy Initialization Judiciously
Favicon
Effective Java: Document Thread Safety
Favicon
Effective Java: Prefer Concurrency Utilities Over wait and notify
Favicon
Effective Java: Prefer Executors, Tasks, and Streams to Threads
Favicon
Effective Java: Avoid Excessive Synchronization
Favicon
Effective Java: Synchronize Access to Shared Mutable Data
Favicon
Effective Java: Don't Ignore Exceptions
Favicon
Effective Java: Strive for Failure Atomicity
Favicon
Effective Java: Include Failure-Capture Information in Detail Messages
Favicon
Effective Java: Document All Exceptions Thrown By Each Method
Favicon
Effective Java: Throw Exceptions Appropriate To The Abstraction
Favicon
Effective Java: Favor The Use of Standard Exceptions
Favicon
Effective Java: Avoid Unnecessary Use of Checked Exceptions
Favicon
Effective Java: Use Checked Exceptions for Recoverable Conditions
Favicon
Effective Java: Use Exceptions for Only Exceptional Circumstances
Favicon
Effective Java: Adhere to Generally Accepted Naming Conventions
Favicon
Effective Java: Optimize Judiciously
Favicon
Effective Java: Use Native Methods Judiciously
Favicon
Effective Java: Prefer Interfaces To Reflection
Favicon
10 effective tips for New Developers

Featured ones: