#1405·chai

Consider a new, informative page in Chai's documentation for working with Errors

Author: jojenkiCreated Jun 25, 2021Updated Jul 30, 2025

Simple working example:

typescript
class UntypedError {
  private readonly message;
  constructor(message: string) {
    this.message = message;
  }
}

class TypedError extends Error {
  constructor(message: string) {
    super(message);
  }
}

describe("Error Experimentation", () => {
  it("should pass in all of these cases", () => {
    // Pass
    expect(new UntypedError("untyped error no array")).to.deep.equal(new UntypedError("untyped error no array"));
    // Fail - This is the unexpected part, to me.
    expect(new TypedError("typed error no array")).to.deep.equal(new TypedError("typed error no array"));

    // This is closer to what I'm actually trying to test but is fundamentally the same thing.
    // Pass
    expect([new UntypedError("untyped error array")]).to.deep.include(new UntypedError("untyped error array"));
    // Fail - The fact that it's part of an array is probably irrelevant, but I cannot be certain.
    expect([new TypedError("typed error array")]).to.deep.include(new TypedError("typed error array"));
  });
});

I've been working on this for a couple of days now and have seen some resources / hints regarding Chai basically making the decision that two Errors with different call-stacks are evaluated as different, even if they are the same type and have the same message. So, I think that's what's going on here.

My ask is that the team create some dedicated documentation that explains this (so I can be certain that that's what is actually going on here) and propose some alternatives or provide a rationale on why this type of testing shouldn't work / shouldn't be done.

And, if such documentation does already exist, I apologize for wasting your time, and my feedback would be that, that documentation is hard to find. :)