Skip to content

Commit 221c769

Browse files
authored
feat(parser): add custom parse error (#2339)
1 parent e0de20b commit 221c769

26 files changed

+241
-78
lines changed

Diff for: packages/parser/src/envelopes/apigw.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
22
import { z, type ZodSchema } from 'zod';
33
import { APIGatewayProxyEventSchema } from '../schemas/apigw.js';
44
import type { ParsedResult } from '../types/parser.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* API Gateway envelope to extract data within body key
@@ -21,7 +22,11 @@ export class ApiGatewayEnvelope extends Envelope {
2122
const parsedEnvelope = APIGatewayProxyEventSchema.safeParse(data);
2223
if (!parsedEnvelope.success) {
2324
return {
24-
...parsedEnvelope,
25+
success: false,
26+
error: new ParseError(
27+
'Failed to parse ApiGatewayEnvelope',
28+
parsedEnvelope.error
29+
),
2530
originalEvent: data,
2631
};
2732
}
@@ -30,7 +35,11 @@ export class ApiGatewayEnvelope extends Envelope {
3035

3136
if (!parsedBody.success) {
3237
return {
33-
...parsedBody,
38+
success: false,
39+
error: new ParseError(
40+
'Failed to parse ApiGatewayEnvelope body',
41+
parsedBody.error
42+
),
3443
originalEvent: data,
3544
};
3645
}

Diff for: packages/parser/src/envelopes/apigwv2.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
22
import { APIGatewayProxyEventV2Schema } from '../schemas/apigwv2.js';
33
import { Envelope } from './envelope.js';
44
import type { ParsedResult } from '../types/index.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* API Gateway V2 envelope to extract data within body key
@@ -21,7 +22,11 @@ export class ApiGatewayV2Envelope extends Envelope {
2122
const parsedEnvelope = APIGatewayProxyEventV2Schema.safeParse(data);
2223
if (!parsedEnvelope.success) {
2324
return {
24-
...parsedEnvelope,
25+
success: false,
26+
error: new ParseError(
27+
'Failed to parse API Gateway V2 envelope',
28+
parsedEnvelope.error
29+
),
2530
originalEvent: data,
2631
};
2732
}
@@ -30,7 +35,11 @@ export class ApiGatewayV2Envelope extends Envelope {
3035

3136
if (!parsedBody.success) {
3237
return {
33-
...parsedBody,
38+
success: false,
39+
error: new ParseError(
40+
'Failed to parse API Gateway V2 envelope body',
41+
parsedBody.error
42+
),
3443
originalEvent: data,
3544
};
3645
}

Diff for: packages/parser/src/envelopes/cloudwatch.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
22
import { Envelope } from './envelope.js';
33
import { CloudWatchLogsSchema } from '../schemas/index.js';
44
import type { ParsedResult } from '../types/index.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* CloudWatch Envelope to extract a List of log records.
@@ -33,7 +34,10 @@ export class CloudWatchEnvelope extends Envelope {
3334
if (!parsedEnvelope.success) {
3435
return {
3536
success: false,
36-
error: parsedEnvelope.error,
37+
error: new ParseError(
38+
'Failed to parse CloudWatch envelope',
39+
parsedEnvelope.error
40+
),
3741
originalEvent: data,
3842
};
3943
}
@@ -44,7 +48,10 @@ export class CloudWatchEnvelope extends Envelope {
4448
if (!parsedMessage.success) {
4549
return {
4650
success: false,
47-
error: parsedMessage.error,
51+
error: new ParseError(
52+
'Failed to parse CloudWatch log event',
53+
parsedMessage.error
54+
),
4855
originalEvent: data,
4956
};
5057
} else {

Diff for: packages/parser/src/envelopes/dynamodb.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
22
import { DynamoDBStreamSchema } from '../schemas/index.js';
33
import type { ParsedResult, ParsedResultError } from '../types/index.js';
44
import { Envelope } from './envelope.js';
5+
import { ParseError } from '../errors.js';
56

67
type DynamoDBStreamEnvelopeResponse<T extends ZodSchema> = {
78
NewImage: z.infer<T>;
@@ -38,7 +39,10 @@ export class DynamoDBStreamEnvelope extends Envelope {
3839
if (!parsedEnvelope.success) {
3940
return {
4041
success: false,
41-
error: parsedEnvelope.error,
42+
error: new ParseError(
43+
'Failed to parse DynamoDB Stream envelope',
44+
parsedEnvelope.error
45+
),
4246
originalEvent: data,
4347
};
4448
}
@@ -51,8 +55,11 @@ export class DynamoDBStreamEnvelope extends Envelope {
5155
return {
5256
success: false,
5357
error: !parsedNewImage.success
54-
? parsedNewImage.error
55-
: (parsedOldImage as ParsedResultError<unknown>).error,
58+
? new ParseError('Failed to parse NewImage', parsedNewImage.error)
59+
: new ParseError(
60+
'Failed to parse OldImage',
61+
(parsedOldImage as ParsedResultError<unknown>).error
62+
),
5663
originalEvent: data,
5764
};
5865
} else {

Diff for: packages/parser/src/envelopes/envelope.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { z, type ZodSchema } from 'zod';
22
import type { ParsedResult } from '../types/parser.js';
3+
import { ParseError } from '../errors.js';
34

45
export class Envelope {
56
/**
@@ -14,14 +15,20 @@ export class Envelope {
1415
data: unknown,
1516
schema: T
1617
): z.infer<T> => {
17-
if (typeof data === 'string') {
18-
return schema.parse(JSON.parse(data));
19-
} else if (typeof data === 'object') {
20-
return schema.parse(data);
21-
} else
22-
throw new Error(
18+
if (typeof data !== 'object' && typeof data !== 'string') {
19+
throw new ParseError(
2320
`Invalid data type for envelope. Expected string or object, got ${typeof data}`
2421
);
22+
}
23+
try {
24+
if (typeof data === 'string') {
25+
return schema.parse(JSON.parse(data));
26+
} else if (typeof data === 'object') {
27+
return schema.parse(data);
28+
}
29+
} catch (e) {
30+
throw new ParseError(`Failed to parse envelope`, e as Error);
31+
}
2532
};
2633

2734
/**
@@ -38,7 +45,7 @@ export class Envelope {
3845
if (typeof input !== 'object' && typeof input !== 'string') {
3946
return {
4047
success: false,
41-
error: new Error(
48+
error: new ParseError(
4249
`Invalid data type for envelope. Expected string or object, got ${typeof input}`
4350
),
4451
originalEvent: input,
@@ -56,13 +63,13 @@ export class Envelope {
5663
}
5764
: {
5865
success: false,
59-
error: parsed.error,
66+
error: new ParseError(`Failed to parse envelope`, parsed.error),
6067
originalEvent: input,
6168
};
6269
} catch (e) {
6370
return {
6471
success: false,
65-
error: e as Error,
72+
error: new ParseError(`Failed to parse envelope`, e as Error),
6673
originalEvent: input,
6774
};
6875
}

Diff for: packages/parser/src/envelopes/event-bridge.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
22
import { z, type ZodSchema } from 'zod';
33
import { EventBridgeSchema } from '../schemas/index.js';
44
import type { ParsedResult } from '../types/index.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* Envelope for EventBridge schema that extracts and parses data from the `detail` key.
@@ -22,7 +23,11 @@ export class EventBridgeEnvelope extends Envelope {
2223

2324
if (!parsedEnvelope.success) {
2425
return {
25-
...parsedEnvelope,
26+
success: false,
27+
error: new ParseError(
28+
'Failed to parse EventBridge envelope',
29+
parsedEnvelope.error
30+
),
2631
originalEvent: data,
2732
};
2833
}
@@ -31,7 +36,11 @@ export class EventBridgeEnvelope extends Envelope {
3136

3237
if (!parsedDetail.success) {
3338
return {
34-
...parsedDetail,
39+
success: false,
40+
error: new ParseError(
41+
'Failed to parse EventBridge envelope detail',
42+
parsedDetail.error
43+
),
3544
originalEvent: data,
3645
};
3746
}

Diff for: packages/parser/src/envelopes/kafka.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
KafkaSelfManagedEventSchema,
66
} from '../schemas/kafka.js';
77
import { ParsedResult, KafkaMskEvent } from '../types/index.js';
8+
import { ParseError } from '../errors.js';
89

910
/**
1011
* Kafka event envelope to extract data within body key
@@ -51,7 +52,11 @@ export class KafkaEnvelope extends Envelope {
5152

5253
if (!parsedEnvelope.success) {
5354
return {
54-
...parsedEnvelope,
55+
success: false,
56+
error: new ParseError(
57+
'Failed to parse Kafka envelope',
58+
parsedEnvelope.error
59+
),
5560
originalEvent: data,
5661
};
5762
}
@@ -63,7 +68,10 @@ export class KafkaEnvelope extends Envelope {
6368
if (!parsedRecord.success) {
6469
return {
6570
success: false,
66-
error: parsedRecord.error,
71+
error: new ParseError(
72+
'Failed to parse Kafka record',
73+
parsedRecord.error
74+
),
6775
originalEvent: data,
6876
};
6977
}

Diff for: packages/parser/src/envelopes/kinesis-firehose.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
22
import { Envelope } from './envelope.js';
33
import { KinesisFirehoseSchema } from '../schemas/index.js';
44
import type { ParsedResult } from '../types/index.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* Kinesis Firehose Envelope to extract array of Records
@@ -35,7 +36,11 @@ export class KinesisFirehoseEnvelope extends Envelope {
3536

3637
if (!parsedEnvelope.success) {
3738
return {
38-
...parsedEnvelope,
39+
success: false,
40+
error: new ParseError(
41+
'Failed to parse Kinesis Firehose envelope',
42+
parsedEnvelope.error
43+
),
3944
originalEvent: data,
4045
};
4146
}
@@ -46,7 +51,10 @@ export class KinesisFirehoseEnvelope extends Envelope {
4651
if (!parsedData.success) {
4752
return {
4853
success: false,
49-
error: parsedData.error,
54+
error: new ParseError(
55+
'Failed to parse Kinesis Firehose record',
56+
parsedData.error
57+
),
5058
originalEvent: data,
5159
};
5260
}

Diff for: packages/parser/src/envelopes/kinesis.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
22
import { z, type ZodSchema } from 'zod';
33
import { KinesisDataStreamSchema } from '../schemas/kinesis.js';
44
import type { ParsedResult } from '../types/index.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* Kinesis Data Stream Envelope to extract array of Records
@@ -32,7 +33,11 @@ export class KinesisEnvelope extends Envelope {
3233
const parsedEnvelope = KinesisDataStreamSchema.safeParse(data);
3334
if (!parsedEnvelope.success) {
3435
return {
35-
...parsedEnvelope,
36+
success: false,
37+
error: new ParseError(
38+
'Failed to parse Kinesis Data Stream envelope',
39+
parsedEnvelope.error
40+
),
3641
originalEvent: data,
3742
};
3843
}
@@ -43,7 +48,11 @@ export class KinesisEnvelope extends Envelope {
4348
const parsedRecord = super.safeParse(record.kinesis.data, schema);
4449
if (!parsedRecord.success) {
4550
return {
46-
...parsedRecord,
51+
success: false,
52+
error: new ParseError(
53+
'Failed to parse Kinesis Data Stream record',
54+
parsedRecord.error
55+
),
4756
originalEvent: data,
4857
};
4958
}

Diff for: packages/parser/src/envelopes/lambda.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
22
import { z, type ZodSchema } from 'zod';
33
import { LambdaFunctionUrlSchema } from '../schemas/index.js';
44
import type { ParsedResult } from '../types/index.js';
5+
import { ParseError } from '../errors.js';
56

67
/**
78
* Lambda function URL envelope to extract data within body key
@@ -28,15 +29,20 @@ export class LambdaFunctionUrlEnvelope extends Envelope {
2829

2930
if (!parsedEnvelope.success) {
3031
return {
31-
...parsedEnvelope,
32+
success: false,
33+
error: new ParseError('Failed to parse Lambda function URL envelope'),
3234
originalEvent: data,
3335
};
3436
}
3537

3638
const parsedBody = super.safeParse(parsedEnvelope.data.body, schema);
3739
if (!parsedBody.success) {
3840
return {
39-
...parsedBody,
41+
success: false,
42+
error: new ParseError(
43+
'Failed to parse Lambda function URL body',
44+
parsedBody.error
45+
),
4046
originalEvent: data,
4147
};
4248
}

0 commit comments

Comments
 (0)