Appearance
Failure handlers
If your function exhausts all of its retries, it will be marked as "Failed." You can handle this circumstance by either providing an onFailure/on_failure handler when defining your function, or by listening for the inngest/function.failed system event.
The first approach is function-specific, while the second covers all function failures in a given Inngest environment.
Examples
The example below checks if a user's subscription is valid a total of six times. If you can't check the subscription after all retries, you'll unsubscribe the user:
ts
/* Option 1: give the inngest function an `onFailure` handler. */
inngest.createFunction(
{
id: "update-subscription",
triggers: { event: "user/subscription.check" },
retries: 5,
onFailure: async ({ event, error }) => {
// if the subscription check fails after all retries, unsubscribe the user
await unsubscribeUser(event.data.userId);
},
},
async ({ event }) => { /* ... */ },
);
/* Option 2: Listens for the [`inngest/function.failed`](/docs-markdown/reference/functions/handling-failures#the-inngest-function-failed-event) system event to catch all failures in the inngest environment*/
inngest.createFunction(
{ id: "handle-any-fn-failure", triggers: { event: "inngest/function.failed" } },
async ({ event }) => { /* ... */ },
);python
# Option 1: give the inngest function an [`on_failure`] handler.
async def update_subscription_failed(ctx: inngest.Context):
# if the subscription check fails after all retries, unsubscribe the user
await unsubscribe_user(ctx.data.userId)
@inngest_client.create_function(
fn_id="update-subscription",
retries=5,
on_failure=update_subscription_failed,
trigger=TriggerEvent(event="user/subscription.check"))
async def update_subscription(ctx: Context):
pass # ...
# Option 2: Listens for the [inngest/function.failed](/docs-markdown/reference/functions/handling-failures#the-inngest-function-failed-event)
# system event to catch all failures in the inngest environment
@inngest_client.create_function(
fn_id="global_failure_handler",
trigger=[
TriggerEvent(event="inngest/function.failed"),
#TriggerEvent(event="inngest/function.cancelled")
],
)
async def global_failure_handler(ctx: Context):
pass # handle all failures, e.g. to send to sentrygo
// the Go SDK doesn't have native way to define failure handlers,
// but you can define one by create a new function that uses
// the "inngest/function.failed" event and an expression:
myFailureHandler := inngestgo.CreateFunction(
client,
inngestgo.FunctionOpts{
ID: "account-created-on-failure",
Name: "Account creation flow: On Failure",
},
inngestgo.EventTrigger(
"inngest/function.failed",
// The full function_id is a concatenated slug of your app id and the
// failing function's "ID"
inngestgo.StrPtr("event.data.function_id == 'my-app-account-created'")
),
func(
ctx context.Context,
input inngestgo.Input[inngestgo.GenericEvent[functionFailedEventData, any]],
) (any, error) {
// Handle your failure here
return nil, nil
}
)
type functionFailedEventData struct {
Error struct {
Message string `json:"message"`
Name string `json:"name"`
} `json:"error"`
FunctionID string `json:"function_id"`
RunID string `json:"run_id"`
}
// How to determine the full function_id to use in the expression?
// 1. Get the "app id" set via "NewHandler"
h := inngestgo.NewHandler("my-app", inngestgo.HandlerOpts{})
// 2. Get the FunctionOpts's ID parameter:
f := inngestgo.CreateFunction(
client,
inngestgo.FunctionOpts{
ID: "account-created",
Name: "Account creation flow",
},
inngestgo.EventTrigger("api/account.created", nil),
AccountCreated,
)
// 3. Join them with a hyphen:
// event.data.function_id == 'my-app-account-created'Callout: To handle cancelled function runs, checkout out this example that uses the inngest/function.cancelled system event.