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.

### **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())) { ... }
```
