Repository navigation
fix(core): match nested event filters when an ancestor key is missing… #5022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "@trigger.dev/core": patch | ||
| --- | ||
|
|
||
| Fix `eventFilterMatches` so nested filters that assert the absence of a value match when an ancestor key is missing or `null`, instead of failing before the filter is evaluated. A missing payload is now matched like an empty object: it's how `$exists` behaves on nested paths elsewhere, and how these filters already behaved for a missing key at the top level. | ||
|
|
||
| This changes the result only for filters whose leaves match a missing key today, i.e. `$exists: false`, `$isNull: false` and `$anythingBut`. Filters that require a value (`$exists: true`, `$startsWith`, `$gt`, value arrays, ...) are unchanged. It fixes `retry.fetch`'s `bodyFilter` (e.g. `{ error: { retryAfter: [{ $exists: false }] } }`) not matching responses that have no `error` object. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,16 +5,17 @@ import type { EventFilter } from "./schemas/eventFilter.js"; | |
| // If the values of the array are objects, then we are doing content filtering | ||
| // An example would be [{ $endsWith: ".png" }, { $startsWith: "images/" } ] | ||
| export function eventFilterMatches(payload: any, filter: EventFilter): boolean { | ||
| if (payload === undefined || payload === null) { | ||
| if (Object.entries(filter).length === 0) { | ||
| return true; | ||
| } else { | ||
| return false; | ||
| } | ||
| } | ||
| // A missing (undefined/null) payload is matched like an empty object, so that a missing payload and | ||
| // a missing key are treated the same way. Filters that assert the absence of a value (`$exists: | ||
| // false`, `$isNull: false`, `$anythingBut`) therefore match when an ancestor key is missing or | ||
| // null, instead of failing before the filter is evaluated. This is the same result nested paths | ||
| // give in MongoDB-style filters, and the same result these filters already gave for a missing key | ||
| // at the top level. Filters that need a value (`$exists: true`, `$startsWith`, `$gt`, ...) still | ||
| // don't match `undefined`. | ||
| const payloadObject = payload === undefined || payload === null ? {} : payload; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Missing parents match empty nested filters When an ancestor is missing, Learn moreAn empty nested object or array matches any present value, but the previous nullish guard rejected it when its parent was missing. The new normalization lets those empty filters succeed despite having no leaf that tests absence. This also changes SDK retry selection because getRetryStrategyForResponse uses this matcher for response bodies. Example: With payload Recommended fix: When traversing a missing or null ancestor, distinguish filters that actually match a missing leaf from vacuous matches produced by empty nested objects or arrays. Preserve the previous result for the latter and add tests for both empty forms. Was this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
| for (const [patternKey, patternValue] of Object.entries(filter)) { | ||
| const payloadValue = payload[patternKey]; | ||
| const payloadValue = payloadObject[patternKey]; | ||
|
|
||
| if (Array.isArray(patternValue)) { | ||
| if (patternValue.length === 0) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔍 Lead the release note with user behavior
The changeset opens with
eventFilterMatchesinstead of the user-visible change to nested filters. Repository guidance asks release notes to lead with user behavior.Was this helpful? React with 👍 or 👎 to provide feedback.