mtcute/docs/guide/dispatcher/errors.md
alina sireneva 690948b8b1
All checks were successful
Build and deploy typedoc / build (push) Successful in 5m15s
chore: moved docs inside the main repo
Co-authored-by: Kamilla 'ova <me@kamillaova.dev>
Co-authored-by: Alina Chebakova <chebakov05@gmail.com>
Co-authored-by: Kravets <57632712+kravetsone@users.noreply.github.com>
Co-authored-by: starkow <hello@starkow.dev>
Co-authored-by: sireneva <150665887+sireneva@users.noreply.github.com>
2025-01-17 08:50:35 +03:00

142 lines
3.2 KiB
Markdown
Executable file

# 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
```