Tag Sentry events with the Sume job id and error category in Python

When a Sume job fails, set sume.job_id and sume.error_category with sentry_sdk.set_tag so one search finds the event, the job and the retryable flag.

5 min readSume
All posts

Read the failed job with GET /v1/jobs/{id}, then call sentry_sdk.set_tags({...}) with the job id, data.job.error.category and retryable before you capture the exception. Sentry binds tags to the isolation scope, so later events in the same unit of work carry them too.

Which fields to tag

Sentry limits a tag key to 200 characters of letters, numbers, underscores, periods, colons and dashes, and a value to 200 characters with no newlines. Job ids and the category enum fit; never put a message string in a tag, because messages can be longer.

Sume fields worth a tag (read 2026-10-04)
Tag keySource in the job payloadWhy
sume.job_iddata.job.idFind the job in the API
sume.error_categorydata.job.error.categoryGroup by validation, quota, queue, timeout
sume.error_stagedata.job.error.stageWhere in the pipeline it stopped
sume.retryabledata.job.error.retryableSeparate noise from bugs

Code

x-sume-request-id is a different identifier from the job id: it names one HTTP exchange. Capture it from the response headers if you need to quote a specific call to support. The snippet tags the job fields, which are what the status payload gives you.

import asyncio, json, os, sys, urllib.request
import sentry_sdk

sentry_sdk.init(dsn=os.environ.get("SENTRY_DSN"))

class SumeJobFailed(Exception):
    pass

def get_job(job_id):
    req = urllib.request.Request(f"https://api.sume.com/v1/jobs/{job_id}",
                                 headers={"x-api-key": os.environ["SUME_API_KEY"]})
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.load(r)["data"]["job"]

async def report(job_id):
    job = await asyncio.to_thread(get_job, job_id)
    err = job.get("error")
    if job["status"] not in ("failed", "canceled") or not err:
        print("nothing to report", job["status"]); return
    sentry_sdk.set_tags({
        "sume.job_id": job["id"],
        "sume.error_category": err["category"],
        "sume.error_stage": err["stage"],
        "sume.retryable": str(err["retryable"]).lower(),
    })
    sentry_sdk.capture_exception(SumeJobFailed(err.get("message", "job failed")[:200]))
    sentry_sdk.flush(5)

asyncio.run(report(sys.argv[1]))

Using the tags

Tagged values let you filter events by job id when a ticket quotes one, and by sume.error_category so quota and validation failures can be routed apart from internal errors. Check the Sentry docs for your plan's tag search behavior.

Long-lived workers

In a long-lived worker loop, tags stay on the scope until you change them, so set them at the start of each job so the previous job's values are overwritten, and keep the message out of the tag value. See the error envelope decision function for what retryable should drive.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume