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.

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.
| Tag key | Source in the job payload | Why |
|---|---|---|
sume.job_id | data.job.id | Find the job in the API |
sume.error_category | data.job.error.category | Group by validation, quota, queue, timeout |
sume.error_stage | data.job.error.stage | Where in the pipeline it stopped |
sume.retryable | data.job.error.retryable | Separate 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
- Stream Sume job progress to a browser with SSE and Node polling
Sume has no SSE or WebSocket job stream, so relay it: a small Node endpoint polls the status route and pushes text/event-stream messages to EventSource.
- One shared key after Sora? Who can read which Sume job
Sume jobs belong to the member whose key created them. If a worker and a web app use different keys, one gets 404 on the other's job. Plan the key layout.
- Shopify rejects file names ending in thumb, icon or large
Shopify file uploads reject names ending in pico, icon, thumb, testing, small, compact, medium, large or grande. A Python rename step for batch outputs.
- Shopify image limits: 20 MB, 25 megapixels vs Sume image outputs
Shopify accepts product images up to 20 MB and 25 megapixels in JPEG, PNG, WEBP, HEIC or GIF. How that lines up with Sume image model sizes and formats.
Written by Sume