Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
maximpoleley authored Nov 12, 2023
2 parents e630c08 + 0b4d5d7 commit d414a51
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 7 deletions.
17 changes: 14 additions & 3 deletions src/consumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { autoBind } from './bind';
import {
SQSError,
TimeoutError,
toStandardError,
toTimeoutError,
toSQSError,
isConnectionError
} from './errors';
Expand Down Expand Up @@ -453,9 +455,15 @@ export class Consumer extends TypedEventEmitter {
return result instanceof Object ? result : message;
} catch (err) {
if (err instanceof TimeoutError) {
err.message = `Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`;
throw toTimeoutError(
err,
`Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`
);
} else if (err instanceof Error) {
err.message = `Unexpected message handler failure: ${err.message}`;
throw toStandardError(
err,
`Unexpected message handler failure: ${err.message}`
);
}
throw err;
} finally {
Expand All @@ -476,7 +484,10 @@ export class Consumer extends TypedEventEmitter {
return result instanceof Object ? result : messages;
} catch (err) {
if (err instanceof Error) {
err.message = `Unexpected message handler failure: ${err.message}`;
throw toStandardError(
err,
`Unexpected message handler failure: ${err.message}`
);
}
throw err;
}
Expand Down
51 changes: 49 additions & 2 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@ class SQSError extends Error {
}

class TimeoutError extends Error {
cause: Error;
time: Date;

constructor(message = 'Operation timed out.') {
super(message);
this.message = message;
this.name = 'TimeoutError';
}
}

class StandardError extends Error {
cause: Error;
time: Date;

constructor(message = 'An unexpected error occurred:') {
super(message);
this.message = message;
this.name = 'StandardError';
}
}

/**
* Checks if the error provided should be treated as a connection error.
* @param err The error that was received.
Expand All @@ -41,7 +55,7 @@ function isConnectionError(err: Error): boolean {
/**
* Formats an AWSError the the SQSError type.
* @param err The error object that was received.
* @param message The message that the error occurred on.
* @param message The message to send with the error.
*/
function toSQSError(err: AWSError, message: string): SQSError {
const sqsError = new SQSError(message);
Expand All @@ -55,4 +69,37 @@ function toSQSError(err: AWSError, message: string): SQSError {
return sqsError;
}

export { SQSError, TimeoutError, isConnectionError, toSQSError };
/**
* Formats an Error to the StandardError type.
* @param err The error object that was received.
* @param message The message to send with the error.
*/
function toStandardError(err: Error, message: string): StandardError {
const error = new StandardError(message);
error.cause = err;
error.time = new Date();

return error;
}

/**
* Formats an Error to the TimeoutError type.
* @param err The error object that was received.
* @param message The message to send with the error.
*/
function toTimeoutError(err: TimeoutError, message: string): TimeoutError {
const error = new TimeoutError(message);
error.cause = err;
error.time = new Date();

return error;
}

export {
SQSError,
TimeoutError,
isConnectionError,
toSQSError,
toStandardError,
toTimeoutError
};
60 changes: 58 additions & 2 deletions test/tests/consumer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ describe('Consumer', () => {
);
});

it('handles non-standard exceptions thrown by the handler function', async () => {
it('handles non-standard objects thrown by the handler function', async () => {
class CustomError {
private _message: string;

Expand Down Expand Up @@ -325,6 +325,33 @@ describe('Consumer', () => {
assert.equal(err.message, 'unexpected parsing error');
});

it('handles non-standard exceptions thrown by the handler function', async () => {
const customError = new Error();
Object.defineProperty(customError, 'message', {
get: () => 'unexpected parsing error'
});

consumer = new Consumer({
queueUrl: QUEUE_URL,
region: REGION,
handleMessage: () => {
throw customError;
},
sqs,
authenticationErrorTimeout: AUTHENTICATION_ERROR_TIMEOUT
});

consumer.start();
const err: any = await pEvent(consumer, 'processing_error');
consumer.stop();

assert.ok(err);
assert.equal(
err.message,
'Unexpected message handler failure: unexpected parsing error'
);
});

it('fires an error event when an error occurs deleting a message', async () => {
const deleteErr = new Error('Delete error');

Expand Down Expand Up @@ -844,7 +871,7 @@ describe('Consumer', () => {
);
});

it('handles non-standard exceptions thrown by the handler batch function', async () => {
it('handles non-standard objects thrown by the handler batch function', async () => {
class CustomError {
private _message: string;

Expand Down Expand Up @@ -877,6 +904,35 @@ describe('Consumer', () => {
assert.equal(err.message, 'unexpected parsing error');
});

it('handles non-standard exceptions thrown by the handler batch function', async () => {
const customError = new Error();
Object.defineProperty(customError, 'message', {
get: () => 'unexpected parsing error'
});

consumer = new Consumer({
queueUrl: QUEUE_URL,
messageAttributeNames: ['attribute-1', 'attribute-2'],
region: REGION,
handleMessageBatch: () => {
throw customError;
},
batchSize: 2,
sqs,
authenticationErrorTimeout: AUTHENTICATION_ERROR_TIMEOUT
});

consumer.start();
const err: any = await pEvent(consumer, 'error');
consumer.stop();

assert.ok(err);
assert.equal(
err.message,
'Unexpected message handler failure: unexpected parsing error'
);
});

it('prefers handleMessagesBatch over handleMessage when both are set', async () => {
consumer = new Consumer({
queueUrl: QUEUE_URL,
Expand Down

0 comments on commit d414a51

Please sign in to comment.