Skip to content

feat(attachments): report attachments that could not be served to Sentry - #89

Draft
gmaclennan wants to merge 2 commits into
feat/attachments-audit-endpointfrom
feat/sentry-attachment-reporting
Draft

gmaclennan wants to merge 2 commits into
feat/attachments-audit-endpointfrom
feat/sentry-attachment-reporting

Conversation

@gmaclennan

@gmaclennan gmaclennan commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Today the only sign that an attachment is partly synced to the cloud is a partner's connector failing downstream: the server logs to stdout and nothing else, so a 404, a 500 with UNKNOWN_ERROR or a 502 from the attachments route goes unnoticed until someone complains.

This adds optional Sentry reporting, on only when SENTRY_DSN is set (@sentry/node is imported on demand, so a deployment without a DSN does not pay for it). The attachments route in src/routes.js now sends one attachment.nonok event for every response it could not serve as a 200, tagged with the project, the first seven characters of the drive id, type, variant, the HTTP status, a coarse class (missing for an upstream 404, incomplete when core resets or truncates, error otherwise) and core's own error code where it sent one; the fetch cause (UND_ERR_SOCKET and the like) goes in the event detail and the pino warn line. The capture function is injected through the server options, so tests run without a DSN. Sentry's unhandled-rejection integration is set to strict so a DSN does not stop the process crashing the way it does today, and the client is flushed on shutdown.

Scope and limits. Sentry is initialised after fastify and core are imported and its ESM loader hook is turned off, so there is no tracing or auto-instrumentation: only crashes, unhandled rejections and the attachment event above are reported, and a 5xx that fastify turns into a response on another route is not. The dependency is @sentry/node 10.x rather than 11.x because 11 requires node 20.19 and the Dockerfile pins 20.17.0. Nothing audits attachments on its own yet.

Related changes. This replaces the Sentry reporting part of #79, which is being split up after review. It stacks on the audit endpoint PR (#88), because the route classifies failures with the upstreamFailure and fetchFailure helpers from src/attachments-audit.js. After digidem/comapeo-core#1350, a partial blob reaches this route as an upstream 404 with code BLOB_NOT_AVAILABLE_ERROR rather than a reset or truncation; the event already carries core's error code. #90 (draft) on top of this one runs the audit after each sync and reports missing attachments.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​sentry/​node@​10.76.2991009596100

View full report

@gmaclennan gmaclennan left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is always detected by Guardian Connector when trying to import from the server, maybe that is enough, rather than dealing with setting up Sentry for every server deployed.

@rudokemper

Copy link
Copy Markdown
Contributor

Akin to #88 (comment), I am also thinking of non Guardian Connector use cases. I remember seeing @luandro's spreadsheet of comapeo-cloud servers, and seeing a number of non-GC deployments. So this could be useful for those servers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants