Skip to content

Commit

Permalink
chore: wrap an Error (so cause can be the original error)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Apr 5, 2024
1 parent cdfa928 commit 08b0c74
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 46 deletions.
8 changes: 4 additions & 4 deletions src/sfError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ export class SfError<T extends ErrorDataProperties = ErrorDataProperties> extend
cause: err,
})
: // ok, something was throws that wasn't error or string. Convert it to an Error that preserves the information as the cause and wrap that.
SfError.create<T>({
message: `SfError.wrap received type ${typeof err} but expects type Error or string`,
cause: err,
});
SfError.wrap<T>(
new Error(`SfError.wrap received type ${typeof err} but expects type Error or string`, { cause: err })
);

// If the original error has a code, use that instead of name.
if (hasString(err, 'code')) {
sfError.code = err.code;
Expand Down
84 changes: 42 additions & 42 deletions test/unit/sfErrorTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,89 +106,89 @@ describe('SfError', () => {
});

describe('wrap', () => {
it('should return a wrapped error', () => {
const myErrorMsg = 'yikes! What did you do?';
const myErrorName = 'OhMyError';
const myError = new Error(myErrorMsg);
myError.name = myErrorName;
const mySfError = SfError.wrap(myError);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.message).to.equal(myErrorMsg);
expect(mySfError.name).to.equal(myErrorName);
expect(mySfError.cause).to.equal(myError);
expect(inspect(mySfError)).to.contain(causeDelimiter).and.contain(myErrorMsg);
});
describe('happy path', () => {
it('should return a wrapped error', () => {
const myErrorMsg = 'yikes! What did you do?';
const myErrorName = 'OhMyError';
const myError = new Error(myErrorMsg);
myError.name = myErrorName;
const mySfError = SfError.wrap(myError);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.message).to.equal(myErrorMsg);
expect(mySfError.name).to.equal(myErrorName);
expect(mySfError.cause).to.equal(myError);
expect(inspect(mySfError)).to.contain(causeDelimiter).and.contain(myErrorMsg);
});

it('should return a wrapped error with a code', () => {
class CodeError extends Error {
public code?: string;
}
const myErrorCode = 'OhMyError';
const myError = new CodeError('test');
myError.code = myErrorCode;
const mySfError = SfError.wrap(myError);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.code).to.equal(myErrorCode);
});
it('should return a wrapped error with a code', () => {
class CodeError extends Error {
public code?: string;
}
const myErrorCode = 'OhMyError';
const myError = new CodeError('test');
myError.code = myErrorCode;
const mySfError = SfError.wrap(myError);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.code).to.equal(myErrorCode);
});

it('should return a new error with just a string', () => {
const mySfError = SfError.wrap('test');
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.message).to.equal('test');
});
it('should return a new error with just a string', () => {
const mySfError = SfError.wrap('test');
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.message).to.equal('test');
});

it('should return the error if already a SfError', () => {
const existingSfError = new SfError('test');
const mySfError = SfError.wrap(existingSfError);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError).to.equal(existingSfError);
it('should return the error if already a SfError', () => {
const existingSfError = new SfError('test');
const mySfError = SfError.wrap(existingSfError);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError).to.equal(existingSfError);
});
});

describe('handling "other" stuff that is not Error', () => {
it('undefined', () => {
const wrapMe = undefined;
const mySfError = SfError.wrap(wrapMe);
expect(mySfError).to.be.an.instanceOf(SfError);
expect(mySfError.message === 'An unexpected error occurred');
expect(mySfError.name === 'TypeError');
assert(mySfError.cause instanceof TypeError);
expect(mySfError.cause.message === 'An unexpected error occurred');
expect(mySfError.message).to.include('SfError.wrap received type ');
assert(mySfError.cause instanceof Error);
expect(mySfError.cause.cause).to.equal(wrapMe);
});
it('a number', () => {
const wrapMe = 2;
const mySfError = SfError.wrap(wrapMe);
expect(mySfError).to.be.an.instanceOf(SfError);
assert(mySfError.cause instanceof TypeError);
assert(mySfError.cause instanceof Error);
expect(mySfError.cause.cause).to.equal(wrapMe);
});
it('an object', () => {
const wrapMe = { a: 2 };
const mySfError = SfError.wrap(wrapMe);
expect(mySfError).to.be.an.instanceOf(SfError);
assert(mySfError.cause instanceof TypeError);
assert(mySfError.cause instanceof Error);
expect(mySfError.cause.cause).to.equal(wrapMe);
});
it('an object that has a code', () => {
const wrapMe = { a: 2, code: 'foo' };
const mySfError = SfError.wrap(wrapMe);
expect(mySfError).to.be.an.instanceOf(SfError);
assert(mySfError.cause instanceof TypeError);
assert(mySfError.cause instanceof Error);
expect(mySfError.cause.cause).to.equal(wrapMe);
expect(mySfError.code).to.equal('foo');
});
it('an array', () => {
const wrapMe = [1, 5, 6];
const mySfError = SfError.wrap(wrapMe);
expect(mySfError).to.be.an.instanceOf(SfError);
assert(mySfError.cause instanceof TypeError);
assert(mySfError.cause instanceof Error);
expect(mySfError.cause.cause).to.equal(wrapMe);
});
it('a class', () => {
const wrapMe = new (class Test {})();
const mySfError = SfError.wrap(wrapMe);
expect(mySfError).to.be.an.instanceOf(SfError);
assert(mySfError.cause instanceof TypeError);
assert(mySfError.cause instanceof Error);
expect(mySfError.cause.cause).to.equal(wrapMe);
});
});
Expand Down

2 comments on commit 08b0c74

@svc-cli-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logger Benchmarks - ubuntu-latest

Benchmark suite Current: 08b0c74 Previous: aed3f3c Ratio
Child logger creation 449455 ops/sec (±1.15%) 475152 ops/sec (±1.29%) 1.06
Logging a string on root logger 775965 ops/sec (±7.41%) 738890 ops/sec (±5.89%) 0.95
Logging an object on root logger 559534 ops/sec (±18.65%) 540081 ops/sec (±8.93%) 0.97
Logging an object with a message on root logger 9135 ops/sec (±203.24%) 16046 ops/sec (±188.10%) 1.76
Logging an object with a redacted prop on root logger 451119 ops/sec (±7.90%) 393676 ops/sec (±12.13%) 0.87
Logging a nested 3-level object on root logger 375816 ops/sec (±6.61%) 342867 ops/sec (±9.78%) 0.91

This comment was automatically generated by workflow using github-action-benchmark.

@svc-cli-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logger Benchmarks - windows-latest

Benchmark suite Current: 08b0c74 Previous: aed3f3c Ratio
Child logger creation 321602 ops/sec (±0.79%) 329489 ops/sec (±0.57%) 1.02
Logging a string on root logger 726720 ops/sec (±4.99%) 776306 ops/sec (±6.24%) 1.07
Logging an object on root logger 634297 ops/sec (±6.23%) 618335 ops/sec (±6.61%) 0.97
Logging an object with a message on root logger 8676 ops/sec (±199.20%) 7206 ops/sec (±203.12%) 0.83
Logging an object with a redacted prop on root logger 444888 ops/sec (±5.96%) 418398 ops/sec (±14.11%) 0.94
Logging a nested 3-level object on root logger 305740 ops/sec (±6.91%) 336244 ops/sec (±5.29%) 1.10

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.