Skip to content

Commit 1448c36

Browse files
fix validationError message body + use LRU/hash for "invalid type" validation errors (#55388)
Co-authored-by: Ashish Keshan <[email protected]> Co-authored-by: Ashish Keshan <[email protected]>
1 parent 74a1ccc commit 1448c36

File tree

2 files changed

+14
-17
lines changed

2 files changed

+14
-17
lines changed

src/events/middleware.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,19 @@ router.post(
4747
const validEvents: any[] = []
4848
const validationErrors: any[] = []
4949

50+
// We use a LRU cache & a hash of the request IP + error message
51+
// to prevent sending multiple validation errors per user that can spam requests to Hydro
52+
const getValidationErrorHash = (validateErrors: ErrorObject[]) =>
53+
`${req.ip}:${(validateErrors || [])
54+
.map(
55+
(error: ErrorObject) => error.message + error.instancePath + JSON.stringify(error.params),
56+
)
57+
.join(':')}`
58+
5059
for (const eventBody of eventsToProcess) {
5160
try {
61+
// Skip event if it doesn't have a type or if the type is not in the allowed types
5262
if (!eventBody.type || !allowedTypes.has(eventBody.type)) {
53-
validationErrors.push({ event: eventBody, error: 'Invalid type' })
5463
continue
5564
}
5665
const type: EventType = eventBody.type
@@ -71,18 +80,7 @@ router.post(
7180
}
7281
const validate = validators[type]
7382
if (!validate(body)) {
74-
validationErrors.push({
75-
event: body,
76-
error: validate.errors || [],
77-
})
78-
// This protects so we don't bother sending the same validation
79-
// error, per user, more than once (per time interval).
80-
// This helps if we're bombarded with junk bot traffic. So it
81-
// protects our Hydro instance from being overloaded with things
82-
// that aren't helping anybody.
83-
const hash = `${req.ip}:${(validate.errors || [])
84-
.map((error: ErrorObject) => error.message + error.instancePath)
85-
.join(':')}`
83+
const hash = getValidationErrorHash(validate.errors || [])
8684
if (!sentValidationErrors.has(hash)) {
8785
sentValidationErrors.set(hash, true)
8886
formatErrors(validate.errors || [], body).map((error) => {

src/events/tests/middleware.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ describe('POST /events', () => {
66
vi.setConfig({ testTimeout: 60 * 1000 })
77

88
async function checkEvent(data: any) {
9-
// if data is not an array, make it one
109
if (!Array.isArray(data)) {
1110
data = [data]
1211
}
@@ -89,9 +88,9 @@ describe('POST /events', () => {
8988
})
9089

9190
test('should require a type', async () => {
92-
const { statusCode, body } = await checkEvent({ ...pageExample, type: undefined })
93-
expect(statusCode).toBe(400)
94-
expect(body).toContain('"error":"Invalid type"}')
91+
const { statusCode } = await checkEvent({ ...pageExample, type: undefined })
92+
// should skip events with no type
93+
expect(statusCode).toBe(200)
9594
})
9695

9796
test('should require an event_id in uuid', async () => {

0 commit comments

Comments
 (0)