Search code examples
pythonflasksentry

What is the equivalent of passing an extra's dictionary to captureException in the new sentry-python SDK?


What is the best way to pass extras to the new sentry-python SDK methods for capture_exception and capture_message?

Previously, I would: sentry_id = sentry.captureException(extra=extra)

Based on the the docs and this github issue (https://github.com/getsentry/sentry-python/issues/113), it like one of the below options is comparable, but I cannot figure out a way.

Using capture_exception is close...

except Exception as e:
    sentry_id = capture_exception(e, extra=extra) # Error

... but doesn't allow for a second extra's paramater :(

Using the python logging integration is very close...

except Exception as e:
    sentry_id = logging.error(e, exc_info=True, extra=extra)

... but doesn't return a sentry id :(

Using both the python logging integration and capture_exception is close...

except Exception as e:
    logging.error(e, exc_info=True, extra=extra)
    sentry_id = capture_exception(e)

... but results in two separate error entries in sentry :(

Using capture_exception with push_scope is close...

except Exception as e:
    with push_scope() as scope:
        scope.set_extra(extra) # Error
        sentry_id = capture_exception(e)

... but doesn't accept a dictionary :(

Is the solution to use the last way, with a helper function which unpacks the extra dict into many scope.set_extra(key, val) calls?

Thanks for the help!


Solution

  • except Exception as e:
        with push_scope() as scope:
            for k, v in extra.items():
                scope.set_extra(k, v)
            sentry_id = capture_exception(e)
    

    However, I would argue that you're setting extra at the wrong point in time. Ideally you would set your extra context data as soon as it becomes available and relevant to the code that is currently executing. Pushing a scope just to call capture_exception indicates a problem with the way you structure your calls to set_extra.

    Instead of this:

    logger.error("Event via logging", extra={"foo": 42})
    
    try:
        1/0
    except Exception:
        with push_scope() as scope:
            scope.set_extra("foo", 42)
            capture_exception()
    

    Do this:

    with push_scope() as scope:
        scope.set_extra("foo", 42)
        logger.error("Event via logging")
    
        try:
            1/0
        except Exception:
            capture_exception()