Skip to content

Commit 0ba9f52

Browse files
committed
fix: onFactoryError not called with foreground factories
1 parent a8da3a8 commit 0ba9f52

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed

packages/bentocache/factories/cache_factory.ts

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export class CacheFactory {
4141
emitter: this.#parameters.emitter,
4242
lockTimeout: this.#parameters.lockTimeout,
4343
serializer: this.#parameters.serializer,
44+
onFactoryError: this.#parameters.onFactoryError,
4445
}).serializeL1Cache(this.#l1Options.serialize ?? true)
4546

4647
const stack = new CacheStack('primary', options, {

packages/bentocache/src/bento_cache_options.ts

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import lodash from '@poppinss/utils/lodash'
33
import string from '@poppinss/utils/string'
44
import { noopLogger } from '@julr/utils/logger'
55

6+
import type { FactoryError } from './errors.js'
67
import { JsonSerializer } from './serializers/json.js'
78
import type {
89
CacheSerializer,
@@ -76,6 +77,7 @@ export class BentoCacheOptions {
7677
* If the L1 cache should be serialized
7778
*/
7879
serializeL1: boolean = true
80+
onFactoryError?: (error: FactoryError) => void
7981

8082
constructor(options: RawBentoCacheOptions) {
8183
this.#options = lodash.merge({}, this, options)
@@ -93,6 +95,7 @@ export class BentoCacheOptions {
9395
this.serializer = this.#options.serializer ?? defaultSerializer
9496

9597
this.logger = this.#options.logger!.child({ pkg: 'bentocache' })
98+
this.onFactoryError = this.#options.onFactoryError
9699
}
97100

98101
serializeL1Cache(shouldSerialize: boolean = true) {

packages/bentocache/src/cache/factory_runner.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ export class FactoryRunner {
4141
await this.#stack.set(key, result, options)
4242
return result
4343
} catch (error) {
44-
if (!isBackground) throw new errors.E_FACTORY_ERROR(key, error)
44+
options.onFactoryError?.(new errors.E_FACTORY_ERROR(key, error, isBackground))
4545

46-
options.onFactoryError?.(new errors.E_FACTORY_ERROR(key, error, true))
46+
if (!isBackground) throw new errors.E_FACTORY_ERROR(key, error)
4747
} finally {
4848
this.#locks.release(key, lockReleaser)
4949
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { test } from '@japa/runner'
2+
import { sleep } from '@julr/utils/misc'
3+
4+
import { throwingFactory } from '../helpers/index.js'
5+
import type { FactoryError } from '../../src/errors.js'
6+
import { CacheFactory } from '../../factories/cache_factory.js'
7+
8+
test.group('Error handling', () => {
9+
test('handle foreground factory error', async ({ assert }) => {
10+
assert.plan(3)
11+
12+
const { cache } = new CacheFactory()
13+
.withL1L2Config()
14+
.merge({
15+
onFactoryError: (error: FactoryError) => {
16+
if (error.cause instanceof Error) {
17+
assert.deepEqual(error.key, 'error')
18+
assert.deepEqual(error.cause?.message, 'Factory error')
19+
assert.deepEqual(error.isBackgroundFactory, false)
20+
}
21+
},
22+
})
23+
.create()
24+
25+
await cache
26+
.getOrSet({ key: 'error', factory: throwingFactory('Factory error') })
27+
.catch(() => {})
28+
})
29+
30+
test('handle background factory error', async ({ assert }) => {
31+
assert.plan(3)
32+
33+
const { cache } = new CacheFactory()
34+
.withL1L2Config()
35+
.merge({
36+
grace: '10m',
37+
onFactoryError: (error: FactoryError) => {
38+
if (error.cause instanceof Error) {
39+
assert.deepEqual(error.key, 'error')
40+
assert.deepEqual(error.cause?.message, 'Factory error')
41+
assert.deepEqual(error.isBackgroundFactory, true)
42+
}
43+
},
44+
})
45+
.create()
46+
47+
await cache.set({ key: 'error', value: 'value', ttl: 10 })
48+
49+
await sleep(50)
50+
51+
await cache
52+
.getOrSet({ key: 'error', factory: throwingFactory('Factory error') })
53+
.catch(() => {})
54+
})
55+
})

0 commit comments

Comments
 (0)