143 lines
3.2 KiB
Markdown
143 lines
3.2 KiB
Markdown
|
# Handling errors
|
||
|
|
||
|
We've already briefly touched handling errors
|
||
|
in dispatchers in the Getting Started section,
|
||
|
but let's dive a bit deeper.
|
||
|
|
||
|
## Registering a handler
|
||
|
|
||
|
An error handler for a Dispatcher is simply a function
|
||
|
that is called whenever an error is thrown inside
|
||
|
one of the handlers.
|
||
|
|
||
|
For convenience, that function has access to the error itself,
|
||
|
the parsed update and the [state](./state) (if applicable):
|
||
|
|
||
|
```ts
|
||
|
dp.onNewMessage(
|
||
|
filters.command('do_stuff'),
|
||
|
async (msg) => {
|
||
|
throw new Error('Some error')
|
||
|
}
|
||
|
)
|
||
|
|
||
|
dp.onError(async (error, update, state) => {
|
||
|
if (update.name === 'new_message') {
|
||
|
await update.data.replyText(`Error: ${error.message}`)
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
})
|
||
|
```
|
||
|
|
||
|
Error handler function is expected to return `boolean` indicating whether
|
||
|
the update was handled. If it was not, it will be propagated to Client.
|
||
|
|
||
|
`update` is an object that contains 2 fields: `name` and `data`.
|
||
|
|
||
|
`name` is simply update name (`new_message`, `edit_message`, etc.;
|
||
|
see [Handlers](handlers.html)), and `data` is the respective object.
|
||
|
|
||
|
|
||
|
## What errors are not handled
|
||
|
|
||
|
Errors inside [Raw update handlers](handlers.html#raw-updates) are not handled
|
||
|
by the error handler. Any other errors within the same dispatcher
|
||
|
(both handlers and filters) are handled by it.
|
||
|
|
||
|
## Propagation
|
||
|
|
||
|
### To Client
|
||
|
|
||
|
If the error handler is not registered, throws an error or returns `false`,
|
||
|
the error is propagated to Client's [error handler](../intro/errors.html#client-errors).
|
||
|
Obviously, in Client's error handler you won't have access to the update
|
||
|
that caused this error:
|
||
|
|
||
|
```ts
|
||
|
dp.onNewMessage(
|
||
|
filters.command('do_stuff'),
|
||
|
async (msg) => {
|
||
|
throw new Error('Some error')
|
||
|
}
|
||
|
)
|
||
|
|
||
|
tg.onError((err) => {
|
||
|
// will be called since there's no `dp.onError`
|
||
|
console.log(err)
|
||
|
})
|
||
|
```
|
||
|
|
||
|
### Within the Dispatcher
|
||
|
|
||
|
When an error is thrown by one of the handlers, propagation within this
|
||
|
dispatcher stops (the same way as if it returned `StopPropagation`):
|
||
|
|
||
|
```ts
|
||
|
dp.onNewMessage(
|
||
|
filters.command('do_stuff'),
|
||
|
async (msg) => {
|
||
|
throw new Error('Some error')
|
||
|
}
|
||
|
)
|
||
|
|
||
|
dp.onNewMessage(
|
||
|
async (msg) => {
|
||
|
// will not reach
|
||
|
}
|
||
|
)
|
||
|
```
|
||
|
|
||
|
### To parent/children
|
||
|
|
||
|
Errors are **not** propagated to parent dispatcher or to any of the children
|
||
|
dispatchers:
|
||
|
|
||
|
```ts
|
||
|
const dp = new Dispatcher(tg)
|
||
|
const dp1 = new Dispatcher()
|
||
|
const dp2 = new Dispatcher()
|
||
|
|
||
|
dp.addChild(dp1)
|
||
|
dp1.addChild(dp2)
|
||
|
|
||
|
// dp --child--> dp1 --child--> dp2
|
||
|
|
||
|
dp.onError(() => console.log('DP caught error'))
|
||
|
dp1.onError(() => console.log('DP1 caught error'))
|
||
|
dp2.onError(() => console.log('DP2 caught error'))
|
||
|
|
||
|
dp1.onNewMessage(() => { throw new Error() })
|
||
|
|
||
|
// Only "DP1 caught error" will ever be printed
|
||
|
```
|
||
|
|
||
|
However, if you need that behaviour, you can use `propagateErrorToParent`:
|
||
|
|
||
|
```ts
|
||
|
const dp = new Dispatcher(tg)
|
||
|
const dp1 = new Dispatcher()
|
||
|
const dp2 = new Dispatcher()
|
||
|
|
||
|
dp.addChild(dp1)
|
||
|
dp1.addChild(dp2)
|
||
|
|
||
|
// dp --child--> dp1 --child--> dp2
|
||
|
|
||
|
dp.onError(() => console.log('DP caught error'))
|
||
|
dp1.onError(() => {
|
||
|
console.log('DP1 caught error')
|
||
|
|
||
|
return dp1.propagateErrorToParent(...arguments)
|
||
|
})
|
||
|
dp2.onError(() => console.log('DP2 caught error'))
|
||
|
|
||
|
dp1.onNewMessage(() => { throw new Error() })
|
||
|
|
||
|
// "DP1 caught error" and "DP caught error" will be printed for each new message
|
||
|
```
|
||
|
|
||
|
|