Error Handling
Understand how you can handle the errors of the CRON Application.
Introduction
When you start a new Athenna project, error and exception handling is already configured for you. But you can configure your own extending the Athenna error handler. We'll dive deeper into how to do that throughout this documentation.
This documentation will cover about error handling in the CRON application, which means that only errors that happens inside schedulers handlers and bellow that will be handled:
import { Cron } from '@athenna/cron'
Cron.schedule()
.name('delete_recent_users')
.pattern('0 0 * * *')
.handler(() => {
throw new Error('CronExceptionHandler will handle this.') 👈
})
throw new Error('This error will be handled by @athenna/core.') 👈
The same applies to your scheduler classes:
import { Scheduler, type Context } from '@athenna/cron'
@Scheduler({ pattern: '0 0 * * *' })
export class DeleteRecentUsers {
public async handler(ctx: Context) {
throw new Error('CronExceptionHandler will handle this.') 👈
}
}
Errors handled by @athenna/core usually means that a
bootstrap failure has been found in your application.
An error thrown inside a scheduler will never stop your CRON application. The exception handler will handle it and your scheduler will keep running in its next executions.
Configuration
The debug option in your
Path.config('app.ts')./src/config/app.ts
APP_DEBUG environment
variable, which is stored in your .env file.
During local development, you should set the APP_DEBUG
environment variable to true. In your production
environment, this value should always be false. If the
value is set to true in production, you risk exposing
sensitive configuration values in your logs.
Every error will be logged by default using the console
driver from @athenna/logger. By default, Athenna uses the
exception channel of your
Path.config('logging.ts')./src/config/logging.ts
You can change the driver and formatter of exception
channel inside
Path.config('logging.ts')./src/config/logging.ts
Prettifying exceptions
By default the exceptions are logged as they are. If you want
to log a prettier version of your exceptions, with colors and
the help message of the exception, set the logger.prettifyException
option of your
Path.config('cron.ts')./src/config/cron.ts
true:
export default {
logger: {
prettifyException: true
}
}
Ignore exceptions by status and code
You can ignore an exception from being logged if its status
code or the code does not match your requirements. To do so
you can add the following configurations to the logger
property in your
Path.config('cron.ts')./src/config/cron.ts
export default {
logger: {
ignoreStatuses: [404],
ignoreCodes: ['E_NOT_FOUND_ERROR']
}
}
From now on, all the exceptions thrown in your CRON
application will not be logged if its status is equal
to 404 or the code is E_NOT_FOUND_ERROR.
Before checking the ignoreCodes option, the exception handler
converts the code of your exception to upper snake case. This
means that an error with the code notFoundError will be
compared as NOT_FOUND_ERROR.
Custom exceptions
You can create custom exception by executing the following Artisan command:
node artisan make:exception NotFoundResourceException
Next, import and raise the exception as follows.
import { NotFoundResourceException } from '#src/exceptions/NotFoundResourceException'
throw new NotFoundResourceException('Your resource has not been found.')
Always try to use a custom exception to throw your errors
inside Athenna. If you use Error, TypeError and other
classes, it will not be treated by the handlers and will
always be considered as a not treated exception.
Implementing your own exception handler
Let's suppose you want to write a custom logic for handling
your exceptions. You can do so by creating your own
exception handler extending CronExceptionHandler:
import { CronExceptionHandler } from '@athenna/cron'
import type { ExceptionHandlerContext } from '@athenna/common'
export class Handler extends CronExceptionHandler {
public async handle(ctx: ExceptionHandlerContext) {
// Implement your own logic
await super.handle(ctx)
}
}
Now you need to register your exception handler when bootstrapping your application:
await ignite.cron({
exceptionHandlerPath: '#src/cron/exceptions/Handler' 👈
})
Setting the exception handler in runtime
You can also set the exception handler of all your schedulers
in runtime using the Cron.setErrorHandler() method. The value
must be an object with a handle() method that receives an
object with the error property:
import { Cron } from '@athenna/cron'
Cron.setErrorHandler({
handle: async ({ error }) => {
console.error(error)
}
})
Schedulers registered while no exception handler was set will
not have their errors handled, even if you set one later. When
using the CRON application this is never a problem, because the
CronKernel registers the exception handler before registering
your schedulers.