Throwables should not override `equals()` or `hashCode()`.

1.  **Exceptions are Events, Not Value Objects** Philosophically, an exception
    represents a unique historical event: something went wrong at a specific
    time, in a specific thread, at a specific line of code. It is not a data
    container or a value type (like a `String` or a `Money` object). Even if two
    `IllegalArgumentException`s are thrown with the exact same message (`"ID
    cannot be null"`), and perhaps even identical stack traces, they represent
    two distinct failures that happened independently. Treating them as "equal"
    conceptually conflates two different events.

2.  **The Stack Trace Problem** When an exception is instantiated (or thrown),
    Java populates its stack trace via `fillInStackTrace()`.

    *   Complexity: Are you going to include the stack trace in your `equals()`
        comparison? If you do, comparing arrays of `StackTraceElement` is
        computationally expensive. Exceptions can also have causes and
        suppressed exceptions. This adds expense, too. Also, will all the
        transitive causes and suppressed exceptions themselves implement
        `equals()` the way you want? Plus, causes and suppressed exceptions make
        exceptions mutable, and mutable objects generally shouldn't implement
        `equals()`.
    *   Brittleness: If you don't include the stack trace, you are saying that
        an exception thrown in `ServiceA` is equal to an exception thrown in
        `ServiceB` just because they share a message or an error code. This
        masks critical debugging context.

3.  **It Hides Bad Architecture** The primary reason you would need to override
    these methods is if you are placing Exceptions into a `HashSet`, or using
    them as keys in a `HashMap`. If you are doing this, you are likely using
    Exceptions for normal business logic or control flow, which is a known
    anti-pattern. Exceptions are for exceptional circumstances; they are heavy
    (because of the stack trace) and slow to generate.

4.  **Java Still Sometimes Compares Exceptions by Object Identity** Even if two
    exceptions are "the same" according to `equals`, Java will still print both
    if it encounters them during a call to `printStackTrace`, and it will allow
    one to be a suppressed exception of the other. In both ways, two exceptions
    that are "the same" will continue to be treated as different by Java.

### **Recommended Alternative: A separate value object**

If you find yourself needing to compare exceptions, **extract the state into a
separate value object.**

Instead of this:

```java
public class UserNotFoundException extends RuntimeException {
  private final String userId;
  private final String groupId;

  // Override equals and hashCode based on userId and groupId...
}
```

Do this: Create a custom Exception that *contains* a value object (like a Record
or a POJO), and compare the value objects instead.

```java
public class UserNotFoundException extends RuntimeException {
  private final ErrorDetails details;

  public UserNotFoundException(ErrorDetails details) {
    super("%s is not a member of %s:".formatted(details.userId(), details.groupId()));
    this.details = details;
  }

  public ErrorDetails getDetails() { return details; }
}

// Compare the details, not the exceptions!
if (e1.getDetails().equals(e2.getDetails())) { ... }
```
