Skip to content

Commit

Permalink
fix: catch dispose error, fix koishijs/koishi#1254
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Nov 13, 2023
1 parent 261ee6b commit 68081c4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ export abstract class EffectScope<C extends Context = Context> {
this.isActive = false
this.disposables = this.disposables.splice(0).filter((dispose) => {
if (this.uid !== null && dispose[Context.static] === this) return true
dispose()
;(async () => dispose())().catch((reason) => {
this.context.emit('internal/warning', reason)
})
})
}

Expand Down
30 changes: 25 additions & 5 deletions tests/dispose.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,38 @@ describe('Disposables', () => {

it('dispose event', () => {
const root = new Context()
const callback = jest.fn(noop)
const dispose = jest.fn(noop)
const plugin = (ctx: Context) => {
ctx.on('dispose', callback)
ctx.on('dispose', dispose)
}

root.plugin(plugin)
expect(callback.mock.calls).to.have.length(0)
expect(dispose.mock.calls).to.have.length(0)
expect(root.dispose(plugin)).to.be.ok
expect(callback.mock.calls).to.have.length(1)
expect(dispose.mock.calls).to.have.length(1)
// callback should only be called once
expect(root.dispose(plugin)).to.be.not.ok
expect(callback.mock.calls).to.have.length(1)
expect(dispose.mock.calls).to.have.length(1)
})

it('dispose event', async () => {
const root = new Context()
const warn = jest.fn()
const dispose = jest.fn(() => {
throw new Error('test')
})
root.on('internal/warning', warn)
const plugin = (ctx: Context) => {
ctx.on('dispose', dispose)
}

root.plugin(plugin)
expect(dispose.mock.calls).to.have.length(0)
expect(root.dispose(plugin)).to.be.ok
// warning is asynchronous
await new Promise((resolve) => setTimeout(resolve, 0))
expect(dispose.mock.calls).to.have.length(1)
expect(warn.mock.calls).to.have.length(1)
})

it('root dispose', async () => {
Expand Down

0 comments on commit 68081c4

Please sign in to comment.