55import warnings
66from typing import Any
77
8+ from taskbadger ._error_context import capture_error_data
9+ from taskbadger .context_providers import ContextProvider
810from taskbadger .exceptions import (
911 ConfigurationError ,
1012 MissingConfiguration ,
@@ -63,6 +65,7 @@ def init(
6365 systems : list [System ] = None ,
6466 tags : dict [str , str ] = None ,
6567 before_create : Callback = None ,
68+ context_providers : list [ContextProvider ] = None ,
6669):
6770 """Initialize Task Badger client.
6871
@@ -73,9 +76,13 @@ def init(
7376 For legacy API keys, *organization_slug* and *project_slug* are
7477 required and a deprecation warning is emitted.
7578
79+ Arguments:
80+ context_providers: Providers consulted when a tracked task errors, to attach extra
81+ context (e.g. a Sentry issue link) to the task's `data`. See `taskbadger.context_providers`.
82+
7683 Call this function once per thread.
7784 """
78- _init (_TB_HOST , organization_slug , project_slug , token , systems , tags , before_create )
85+ _init (_TB_HOST , organization_slug , project_slug , token , systems , tags , before_create , context_providers )
7986
8087
8188def _init (
@@ -86,6 +93,7 @@ def _init(
8693 systems : list [System ] = None ,
8794 tags : dict [str , str ] = None ,
8895 before_create : Callback = None ,
96+ context_providers : list [ContextProvider ] = None ,
8997):
9098 host = host or os .environ .get ("TASKBADGER_HOST" , "https://taskbadger.net" )
9199 organization_slug = organization_slug or os .environ .get ("TASKBADGER_ORG" )
@@ -118,6 +126,7 @@ def _init(
118126 project_slug ,
119127 systems = {system .identifier : system for system in systems },
120128 before_create = before_create ,
129+ context_providers = context_providers or [],
121130 )
122131 Badger .current .bind (settings , tags )
123132 else :
@@ -387,8 +396,19 @@ def success(self, value: int = None):
387396 """Update the task status to `success` and set the value."""
388397 self .update (status = StatusEnum .SUCCESS , value = value )
389398
390- def error (self , value : int = None , data : dict = None ):
391- """Update the task status to `error` and set the value and data."""
399+ def error (self , value : int = None , data : dict = None , exception : BaseException = None ):
400+ """Update the task status to `error` and set the value and data.
401+
402+ If `exception` is given, it's passed to any configured context providers
403+ (e.g. Sentry, see [taskbadger.context_providers][]) and the result merged into `data`.
404+ Called on its own (outside `@track` or the Celery/Procrastinate integrations), providers
405+ have no baseline to compare against, so e.g. `SentryContextProvider` will report whatever
406+ `sentry_sdk.last_event_id()` currently is.
407+ """
408+ if exception is not None :
409+ error_data = capture_error_data (exception )
410+ error_data .update (data or {})
411+ data = error_data
392412 self .update (status = StatusEnum .ERROR , value = value , data = data )
393413
394414 def canceled (self ):
0 commit comments