dherault / dherault/serverless-offline
errorType overriden on custom typescript exception
- Dominant language
- JavaScript
- Stars
- 5.3k
- Forks
- 811
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 3
Description
**Current Behavior**
In a step function, with retriers defined, orchestrating typescript lambdas, if the lambda throws a custom exception, the retrier does not work because serverless-offline changes the errorType to "Error" instead of populating the value of err.name. The result is that the lambda is executed only once and it fails.
Here is the log output:
`[Serverless Step Functions Local] 2022-12-16 17:41:19.675: arn:aws:states:...:my-lambda:... : {"Type":"TaskFailed","PreviousEventId":18,"TaskFailedEventDetails":{"ResourceType":"lambda","Resource":"invoke","Error":"Error","Cause":"{\"errorType\":\"Error\",\"errorMessage\":\"INFO: Lambda is initializing your function. It will be ready to invoke shortly.\",`
**Sample Code**
- file: serverless.yml
```yaml
plugins:
- serverless-plugin-typescript
- serverless-plugin-tracing
- serverless-plugin-conditional-functions
- serverless-s3-local
- serverless-step-functions
- serverless-step-functions-local
- serverless-offline-elasticmq
- serverless-offline-sqs
- serverless-offline
- serverless-iam-roles-per-function
...
Type: Task,
Resource: arn:aws:states:::lambda:invoke,
TimeoutSeconds: 60,
HeartbeatSeconds: 10,
Retry: [{
ErrorEquals: [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.CodeArtifactUserPendingException",
"CodeArtifactUserPendingException"
],
IntervalSeconds: 3,
MaxAttempts: 3,
BackoffRate: 2
```
- file: my-lambda.ts
```ts
const exception = new CodeArtifactUserPendingException(
'INFO: Lambda is initializing your function. It will be ready to invoke shortly.',
);
throw exception;
```
- file: errors.ts
```tsimport { AWSError } from 'aws-sdk';
import { v4 as uuid } from 'uuid';
abstract class MockAWSException extends Error implements AWSError {
readonly code: string;
readonly retryable?: boolean | undefined;
readonly statusCode?: number | undefined;
readonly time: Date;
readonly requestId?: string | undefined;
protected constructor(
readonly message: string,
{
retryable,
statusCode,
}: {
retryable?: boolean | undefined;
statusCode?: number | undefined;
},
) {
super(message);
this.code = this.constructor.name;
this.name = this.constructor.name;
this.time = new Date();
this.requestId = uuid();
this.statusCode = statusCode;
this.retryable = retryable;
Error.captureStackTrace(this, this.constructor);
}
}
export class CodeArtifactUserPendingException extends MockAWSException {
constructor(readonly message: string) {
super(message, {
statusCode: 500,
retryable: true,
});
}
}
```
**Expected behavior/code**
The retriers defined in the step functions definition should be applied, meaning that the lambda should be executed 3 times before failing. And the log output should be:
`[Serverless Step Functions Local] 2022-12-16 17:41:19.675: arn:aws:states:...:my-lambda:... : {"Type":"TaskFailed","PreviousEventId":18,"TaskFailedEventDetails":{"ResourceType":"lambda","Resource":"invoke","Error":"CodeArtifactUserPendingException","Cause":"{\"errorType\":\"CodeArtifactUserPendingException\",\"errorMessage\":\"INFO: Lambda is initializing your function. It will be ready to invoke shortly.\",`
**Environment**
- `serverless` version: 3.21.0
- `serverless-offline` version: 8.8.1
- `node.js` version: 14.18.1
**Possible Solution**
Line 60, in the following file:
src/lambda/routes/invocations/InvocationsController.js
replace `errorType: 'Error',` with `errorType: err.name !== undefined ? err.name : 'Error',`
Contributor guide
Research direction
Start at src/lambda/routes/invocations/InvocationsController.js around line 60 and reproduce the supplied serverless.yml step-function setup with the TypeScript lambda and custom exception. Verify that the invocation preserves the exception name in the failure output and that the configured retrier executes the lambda three times.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, javascript, node.js, typescript
- Domain
- backend, cloud
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100