Skip to content

Commit

Permalink
feat(parser): add custom parse error (#2339)
Browse files Browse the repository at this point in the history
  • Loading branch information
am29d authored Apr 9, 2024
1 parent e0de20b commit 221c769
Show file tree
Hide file tree
Showing 26 changed files with 241 additions and 78 deletions.
13 changes: 11 additions & 2 deletions packages/parser/src/envelopes/apigw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
import { z, type ZodSchema } from 'zod';
import { APIGatewayProxyEventSchema } from '../schemas/apigw.js';
import type { ParsedResult } from '../types/parser.js';
import { ParseError } from '../errors.js';

/**
* API Gateway envelope to extract data within body key
Expand All @@ -21,7 +22,11 @@ export class ApiGatewayEnvelope extends Envelope {
const parsedEnvelope = APIGatewayProxyEventSchema.safeParse(data);
if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError(
'Failed to parse ApiGatewayEnvelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -30,7 +35,11 @@ export class ApiGatewayEnvelope extends Envelope {

if (!parsedBody.success) {
return {
...parsedBody,
success: false,
error: new ParseError(
'Failed to parse ApiGatewayEnvelope body',
parsedBody.error
),
originalEvent: data,
};
}
Expand Down
13 changes: 11 additions & 2 deletions packages/parser/src/envelopes/apigwv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
import { APIGatewayProxyEventV2Schema } from '../schemas/apigwv2.js';
import { Envelope } from './envelope.js';
import type { ParsedResult } from '../types/index.js';
import { ParseError } from '../errors.js';

/**
* API Gateway V2 envelope to extract data within body key
Expand All @@ -21,7 +22,11 @@ export class ApiGatewayV2Envelope extends Envelope {
const parsedEnvelope = APIGatewayProxyEventV2Schema.safeParse(data);
if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError(
'Failed to parse API Gateway V2 envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -30,7 +35,11 @@ export class ApiGatewayV2Envelope extends Envelope {

if (!parsedBody.success) {
return {
...parsedBody,
success: false,
error: new ParseError(
'Failed to parse API Gateway V2 envelope body',
parsedBody.error
),
originalEvent: data,
};
}
Expand Down
11 changes: 9 additions & 2 deletions packages/parser/src/envelopes/cloudwatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
import { Envelope } from './envelope.js';
import { CloudWatchLogsSchema } from '../schemas/index.js';
import type { ParsedResult } from '../types/index.js';
import { ParseError } from '../errors.js';

/**
* CloudWatch Envelope to extract a List of log records.
Expand Down Expand Up @@ -33,7 +34,10 @@ export class CloudWatchEnvelope extends Envelope {
if (!parsedEnvelope.success) {
return {
success: false,
error: parsedEnvelope.error,
error: new ParseError(
'Failed to parse CloudWatch envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -44,7 +48,10 @@ export class CloudWatchEnvelope extends Envelope {
if (!parsedMessage.success) {
return {
success: false,
error: parsedMessage.error,
error: new ParseError(
'Failed to parse CloudWatch log event',
parsedMessage.error
),
originalEvent: data,
};
} else {
Expand Down
13 changes: 10 additions & 3 deletions packages/parser/src/envelopes/dynamodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
import { DynamoDBStreamSchema } from '../schemas/index.js';
import type { ParsedResult, ParsedResultError } from '../types/index.js';
import { Envelope } from './envelope.js';
import { ParseError } from '../errors.js';

type DynamoDBStreamEnvelopeResponse<T extends ZodSchema> = {
NewImage: z.infer<T>;
Expand Down Expand Up @@ -38,7 +39,10 @@ export class DynamoDBStreamEnvelope extends Envelope {
if (!parsedEnvelope.success) {
return {
success: false,
error: parsedEnvelope.error,
error: new ParseError(
'Failed to parse DynamoDB Stream envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -51,8 +55,11 @@ export class DynamoDBStreamEnvelope extends Envelope {
return {
success: false,
error: !parsedNewImage.success
? parsedNewImage.error
: (parsedOldImage as ParsedResultError<unknown>).error,
? new ParseError('Failed to parse NewImage', parsedNewImage.error)
: new ParseError(
'Failed to parse OldImage',
(parsedOldImage as ParsedResultError<unknown>).error
),
originalEvent: data,
};
} else {
Expand Down
25 changes: 16 additions & 9 deletions packages/parser/src/envelopes/envelope.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { z, type ZodSchema } from 'zod';
import type { ParsedResult } from '../types/parser.js';
import { ParseError } from '../errors.js';

export class Envelope {
/**
Expand All @@ -14,14 +15,20 @@ export class Envelope {
data: unknown,
schema: T
): z.infer<T> => {
if (typeof data === 'string') {
return schema.parse(JSON.parse(data));
} else if (typeof data === 'object') {
return schema.parse(data);
} else
throw new Error(
if (typeof data !== 'object' && typeof data !== 'string') {
throw new ParseError(
`Invalid data type for envelope. Expected string or object, got ${typeof data}`
);
}
try {
if (typeof data === 'string') {
return schema.parse(JSON.parse(data));
} else if (typeof data === 'object') {
return schema.parse(data);
}
} catch (e) {
throw new ParseError(`Failed to parse envelope`, e as Error);
}
};

/**
Expand All @@ -38,7 +45,7 @@ export class Envelope {
if (typeof input !== 'object' && typeof input !== 'string') {
return {
success: false,
error: new Error(
error: new ParseError(
`Invalid data type for envelope. Expected string or object, got ${typeof input}`
),
originalEvent: input,
Expand All @@ -56,13 +63,13 @@ export class Envelope {
}
: {
success: false,
error: parsed.error,
error: new ParseError(`Failed to parse envelope`, parsed.error),
originalEvent: input,
};
} catch (e) {
return {
success: false,
error: e as Error,
error: new ParseError(`Failed to parse envelope`, e as Error),
originalEvent: input,
};
}
Expand Down
13 changes: 11 additions & 2 deletions packages/parser/src/envelopes/event-bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
import { z, type ZodSchema } from 'zod';
import { EventBridgeSchema } from '../schemas/index.js';
import type { ParsedResult } from '../types/index.js';
import { ParseError } from '../errors.js';

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

if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError(
'Failed to parse EventBridge envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -31,7 +36,11 @@ export class EventBridgeEnvelope extends Envelope {

if (!parsedDetail.success) {
return {
...parsedDetail,
success: false,
error: new ParseError(
'Failed to parse EventBridge envelope detail',
parsedDetail.error
),
originalEvent: data,
};
}
Expand Down
12 changes: 10 additions & 2 deletions packages/parser/src/envelopes/kafka.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
KafkaSelfManagedEventSchema,
} from '../schemas/kafka.js';
import { ParsedResult, KafkaMskEvent } from '../types/index.js';
import { ParseError } from '../errors.js';

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

if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError(
'Failed to parse Kafka envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -63,7 +68,10 @@ export class KafkaEnvelope extends Envelope {
if (!parsedRecord.success) {
return {
success: false,
error: parsedRecord.error,
error: new ParseError(
'Failed to parse Kafka record',
parsedRecord.error
),
originalEvent: data,
};
}
Expand Down
12 changes: 10 additions & 2 deletions packages/parser/src/envelopes/kinesis-firehose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { z, type ZodSchema } from 'zod';
import { Envelope } from './envelope.js';
import { KinesisFirehoseSchema } from '../schemas/index.js';
import type { ParsedResult } from '../types/index.js';
import { ParseError } from '../errors.js';

/**
* Kinesis Firehose Envelope to extract array of Records
Expand Down Expand Up @@ -35,7 +36,11 @@ export class KinesisFirehoseEnvelope extends Envelope {

if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError(
'Failed to parse Kinesis Firehose envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -46,7 +51,10 @@ export class KinesisFirehoseEnvelope extends Envelope {
if (!parsedData.success) {
return {
success: false,
error: parsedData.error,
error: new ParseError(
'Failed to parse Kinesis Firehose record',
parsedData.error
),
originalEvent: data,
};
}
Expand Down
13 changes: 11 additions & 2 deletions packages/parser/src/envelopes/kinesis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
import { z, type ZodSchema } from 'zod';
import { KinesisDataStreamSchema } from '../schemas/kinesis.js';
import type { ParsedResult } from '../types/index.js';
import { ParseError } from '../errors.js';

/**
* Kinesis Data Stream Envelope to extract array of Records
Expand Down Expand Up @@ -32,7 +33,11 @@ export class KinesisEnvelope extends Envelope {
const parsedEnvelope = KinesisDataStreamSchema.safeParse(data);
if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError(
'Failed to parse Kinesis Data Stream envelope',
parsedEnvelope.error
),
originalEvent: data,
};
}
Expand All @@ -43,7 +48,11 @@ export class KinesisEnvelope extends Envelope {
const parsedRecord = super.safeParse(record.kinesis.data, schema);
if (!parsedRecord.success) {
return {
...parsedRecord,
success: false,
error: new ParseError(
'Failed to parse Kinesis Data Stream record',
parsedRecord.error
),
originalEvent: data,
};
}
Expand Down
10 changes: 8 additions & 2 deletions packages/parser/src/envelopes/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Envelope } from './envelope.js';
import { z, type ZodSchema } from 'zod';
import { LambdaFunctionUrlSchema } from '../schemas/index.js';
import type { ParsedResult } from '../types/index.js';
import { ParseError } from '../errors.js';

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

if (!parsedEnvelope.success) {
return {
...parsedEnvelope,
success: false,
error: new ParseError('Failed to parse Lambda function URL envelope'),
originalEvent: data,
};
}

const parsedBody = super.safeParse(parsedEnvelope.data.body, schema);
if (!parsedBody.success) {
return {
...parsedBody,
success: false,
error: new ParseError(
'Failed to parse Lambda function URL body',
parsedBody.error
),
originalEvent: data,
};
}
Expand Down
Loading

0 comments on commit 221c769

Please sign in to comment.