Skip to content

Commit c5066da

Browse files
Merge pull request #8 from hcengineering/fix-uptrace-filter
Fix Uptrace filter is not a function error
2 parents 8ce21fa + 827920e commit c5066da

File tree

2 files changed

+164
-3
lines changed

2 files changed

+164
-3
lines changed

packages/core/src/__tests__/operator.test.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,4 +395,141 @@ describe('operator', () => {
395395
expect(() => _getOperator('$invalid')).toThrow('unknown operator: $invalid')
396396
})
397397
})
398+
399+
describe('operator error handling', () => {
400+
describe('$pull with non-array values', () => {
401+
it('should handle string value instead of array', () => {
402+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: 'not-an-array' } as unknown as Doc
403+
const operator = _getOperator('$pull')
404+
operator(doc, { field: 'value' })
405+
expect((doc as any).field).toEqual([])
406+
})
407+
408+
it('should handle object value instead of array', () => {
409+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: { key: 'value' } } as unknown as Doc
410+
const operator = _getOperator('$pull')
411+
operator(doc, { field: 'value' })
412+
expect((doc as any).field).toEqual([])
413+
})
414+
415+
it('should handle number value instead of array', () => {
416+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: 42 } as unknown as Doc
417+
const operator = _getOperator('$pull')
418+
operator(doc, { field: 'value' })
419+
expect((doc as any).field).toEqual([])
420+
})
421+
422+
it('should handle null value', () => {
423+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: null } as unknown as Doc
424+
const operator = _getOperator('$pull')
425+
operator(doc, { field: 'value' })
426+
expect((doc as any).field).toEqual([])
427+
})
428+
429+
it('should work correctly with valid array', () => {
430+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: [1, 2, 3] } as unknown as Doc
431+
const operator = _getOperator('$pull')
432+
operator(doc, { field: 2 })
433+
expect((doc as any).field).toEqual([1, 3])
434+
})
435+
})
436+
437+
describe('$update with non-array values', () => {
438+
it('should handle string value instead of array', () => {
439+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: 'not-an-array' } as unknown as Doc
440+
const operator = _getOperator('$update')
441+
operator(doc, { field: { $query: { id: 1 }, $update: { value: 'new' } } })
442+
expect((doc as any).field).toEqual([])
443+
})
444+
445+
it('should handle object value instead of array', () => {
446+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: { key: 'value' } } as unknown as Doc
447+
const operator = _getOperator('$update')
448+
operator(doc, { field: { $query: { id: 1 }, $update: { value: 'new' } } })
449+
expect((doc as any).field).toEqual([])
450+
})
451+
452+
it('should handle null value', () => {
453+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, field: null } as unknown as Doc
454+
const operator = _getOperator('$update')
455+
operator(doc, { field: { $query: { id: 1 }, $update: { value: 'new' } } })
456+
expect((doc as any).field).toEqual([])
457+
})
458+
459+
it('should work correctly with valid array', () => {
460+
const doc: Doc = {
461+
_id: '1' as any,
462+
_class: 'test' as any,
463+
field: [
464+
{ id: 1, value: 'old' },
465+
{ id: 2, value: 'keep' }
466+
]
467+
} as unknown as Doc
468+
const operator = _getOperator('$update')
469+
operator(doc, { field: { $query: { id: 1 }, $update: { value: 'new' } } })
470+
expect((doc as any).field).toEqual([
471+
{ id: 1, value: 'new' },
472+
{ id: 2, value: 'keep' }
473+
])
474+
})
475+
})
476+
477+
describe('$inc with non-numeric values', () => {
478+
it('should handle NaN current value', () => {
479+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: NaN } as unknown as Doc
480+
const operator = _getOperator('$inc')
481+
operator(doc, { count: 5 })
482+
expect((doc as any).count).toBe(5)
483+
})
484+
485+
it('should handle string current value', () => {
486+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: 'not-a-number' } as unknown as Doc
487+
const operator = _getOperator('$inc')
488+
operator(doc, { count: 5 })
489+
expect((doc as any).count).toBe(5)
490+
})
491+
492+
it('should handle NaN increment value', () => {
493+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: 10 } as unknown as Doc
494+
const operator = _getOperator('$inc')
495+
operator(doc, { count: NaN })
496+
expect((doc as any).count).toBe(10)
497+
})
498+
499+
it('should handle string increment value', () => {
500+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: 10 } as unknown as Doc
501+
const operator = _getOperator('$inc')
502+
operator(doc, { count: 'not-a-number' as any })
503+
expect((doc as any).count).toBe(10)
504+
})
505+
506+
it('should handle undefined current value (should default to 0)', () => {
507+
const doc: Doc = { _id: '1' as any, _class: 'test' as any } as unknown as Doc
508+
const operator = _getOperator('$inc')
509+
operator(doc, { count: 5 })
510+
expect((doc as any).count).toBe(5)
511+
})
512+
513+
it('should work correctly with valid numbers', () => {
514+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: 10 } as unknown as Doc
515+
const operator = _getOperator('$inc')
516+
operator(doc, { count: 5 })
517+
expect((doc as any).count).toBe(15)
518+
})
519+
520+
it('should handle negative increments', () => {
521+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: 10 } as unknown as Doc
522+
const operator = _getOperator('$inc')
523+
operator(doc, { count: -3 })
524+
expect((doc as any).count).toBe(7)
525+
})
526+
527+
it('should handle zero increment', () => {
528+
const doc: Doc = { _id: '1' as any, _class: 'test' as any, count: 10 } as unknown as Doc
529+
const operator = _getOperator('$inc')
530+
operator(doc, { count: 0 })
531+
expect((doc as any).count).toBe(10)
532+
})
533+
})
534+
})
398535
})

packages/core/src/operator.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ function $pull (document: Doc, keyval: Record<string, PropertyType>): void {
6161
if (doc[key] === undefined) {
6262
doc[key] = []
6363
}
64-
const arr = doc[key] as Array<any>
64+
// Ensure doc[key] is an array before attempting to filter
65+
if (!Array.isArray(doc[key])) {
66+
Analytics.handleError(new Error(`$pull operation on non-array field: ${key}, value: ${JSON.stringify(doc[key])}`))
67+
doc[key] = []
68+
continue
69+
}
70+
const arr = doc[key]
6571
const kvk = keyval[key]
6672
if (typeof kvk === 'object' && kvk !== null) {
6773
const { $in } = kvk as PullArray<PropertyType>
@@ -111,9 +117,15 @@ function $update (document: Doc, keyval: Record<string, PropertyType>): void {
111117
if (doc[key] === undefined) {
112118
doc[key] = []
113119
}
120+
// Ensure doc[key] is an array before attempting to update
121+
if (!Array.isArray(doc[key])) {
122+
Analytics.handleError(new Error(`$update operation on non-array field: ${key}, value: ${JSON.stringify(doc[key])}`))
123+
doc[key] = []
124+
continue
125+
}
114126
const val = keyval[key]
115127
if (typeof val === 'object') {
116-
const arr = doc[key] as Array<any>
128+
const arr = doc[key]
117129
const desc = val as QueryUpdate<PropertyType>
118130
for (const m of matchArrayElement(arr, desc.$query)) {
119131
for (const [k, v] of Object.entries(desc.$update)) {
@@ -128,7 +140,19 @@ function $inc (document: Doc, keyval: Record<string, number>): void {
128140
const doc = document as unknown as Record<string, number | undefined>
129141
for (const key in keyval) {
130142
const cur = doc[key] ?? 0
131-
doc[key] = cur + keyval[key]
143+
// Ensure current value is a number
144+
if (typeof cur !== 'number' || isNaN(cur)) {
145+
Analytics.handleError(new Error(`$inc operation on non-numeric field: ${key}, value: ${JSON.stringify(doc[key])}`))
146+
doc[key] = keyval[key]
147+
continue
148+
}
149+
const increment = keyval[key]
150+
// Ensure increment value is a valid number
151+
if (typeof increment !== 'number' || isNaN(increment)) {
152+
Analytics.handleError(new Error(`$inc operation with invalid increment: ${key}, increment: ${JSON.stringify(increment)}`))
153+
continue
154+
}
155+
doc[key] = cur + increment
132156
}
133157
}
134158

0 commit comments

Comments
 (0)