@spindlecommerce/plugin-sentry
v1.0.0
Published
Sentry for SpindleCommerce: the unexpected errors the platform catches, with their stack traces and where they happened, sent to Sentry.
Maintainers
Readme
Sentry, a SpindleCommerce plugin
Sends the unexpected errors SpindleCommerce catches to Sentry: one event per error, with its stack trace and where it happened.
The plugin receives what the platform passes to plugins' onError hook: every unexpected error the
platform catches and logs. Each report says where the error was caught, and Sentry shows it as the
source tag:
| Source | Where |
|---|---|
| graphql | A GraphQL request. In production the client sees INTERNAL_SERVER_ERROR; Sentry gets the error. |
| route | A plugin's HTTP route. |
| payment-webhook | A payment webhook that could not be processed. |
| plugin-event | A plugin's event handler, on each attempt. |
| plugin-task | A plugin's scheduled task. |
| plugin-hook | A plugin's checkoutValidate, which checkout then ignores. |
| plugin-start | A plugin's onStart. |
| worker | A background worker run. |
It needs plugin SDK 1.1, the version that added onError, and has no dependencies of its own: it
sends events to Sentry's ingestion API itself.
Setup
Find the DSN. In Sentry, create a project for the installation (platform: Node.js) or pick an existing one, and copy its DSN from Project Settings › Client Keys (DSN).
Add the plugin to your SpindleCommerce installation and deploy:
pnpm add @spindlecommerce/plugin-sentry// ecom.config.ts import { sentry } from "@spindlecommerce/plugin-sentry"; export default defineConfig({ plugins: [email(), stripe(), sentry()] });Settings › Plugins › Sentry. Paste the DSN. On a server, the
SENTRY_DSNenvironment variable can supply it instead.Test connection sends a test event and says whether Sentry accepted it, naming the project. The test event appears in Sentry, in the project's issues, as "SpindleCommerce connection test" at level info.
Settings
- DSN (secret,
SENTRY_DSN):https://<key>@<host>/<project id>, with a path before the project id for Sentry installed under one. Older DSNs with a secret key (<key>:<secret>@) work too; the secret is not used. - Environment (
SENTRY_ENVIRONMENT, defaultproduction): tells this installation's errors from those of others sending to the same project, such asstaging. - Release (
SENTRY_RELEASE, optional): the version deployed, such as the git commit. Sentry then says which release an error first appeared in.
What's reported and what isn't
Each report becomes one event:
- The error: its name and message, and its stack trace.
- Frames are oldest first, with function, file, line and column.
- Frames in
node_modules, Node's own code (node:…) and V8's built-ins are marked as outside the app (in_app: false), so Sentry highlights the installation's own code.
- Tags:
source, as above, andpluginwhen a plugin was involved. - Additional data: the report's details, such as a route's method and path, or an event handler's event type and attempt.
- Context: the time the error happened, the environment and release, level
errorand loggerspindlecommerce. - A fingerprint, so that Sentry groups repeats into one issue.
- It is made of the source, the error's name and message, and the function and file of the most recent frame of the app's code.
- Line numbers are left out, so an issue survives a deployment that moves the code.
- Messages that include ids or amounts make one issue per message.
Not reported:
- Expected outcomes of requests, such as validation errors, declined payments and unknown ids.
The platform does not pass them to
onError. - Errors the platform does not catch, such as a crash on startup, and errors in the admin or the storefront in the browser. Use Sentry's own SDKs for those.
- Anything beyond the report: no requests, users, cookies or breadcrumbs. Error messages are sent as they are, though, so a message that includes an email address sends it to Sentry. Sentry's server-side data scrubbing can remove such data.
Rate limiting
An error that repeats, on every request say, should not flood Sentry or use up its quota.
- Repeats. A report whose fingerprint was sent in the last 60 seconds is skipped.
- The memory is kept per process, so each server or serverless instance sends its first occurrence.
- A report counts as sent when it is sent, whatever Sentry answers: an error that repeats while Sentry is down is tried once a minute.
- Sentry's limits. When Sentry answers 429, or announces a limit on errors in
X-Sentry-Rate-Limits(as it does when a quota is used up), nothing is sent until the limit ends.- The limit lasts as long as
Retry-AfterorX-Sentry-Rate-Limitssays, or a minute when a 429 says neither. - Test connection says so instead of sending.
- The limit lasts as long as
- Failures. When Sentry refuses an event or cannot be reached, the plugin logs a warning (never the DSN) and drops the event. It never throws for an HTTP failure, and does not retry.
- Time. Events are sent in the background: the platform runs
onErrorafter catching an error and keeps a serverless function alive for it. Each send waits for Sentry for at most 4 seconds, within the platform's 5 seconds for the hook.
Develop
pnpm install
pnpm test
pnpm buildThe tests run the plugin against a fake Sentry endpoint. The plugin API it builds on is @spindlecommerce/plugin-sdk.
Release
Each version is staged on npm and goes live when a maintainer approves it.
- Raise
versioninpackage.jsonand insrc/index.ts. A test checks they match. - Commit, then tag and push: for example
git tag v1.0.1 && git push origin main v1.0.1. - The Release workflow tests, builds and stages the version, and creates the GitHub release.
- Approve it on npmjs.com, under Staged Packages, with 2FA.
The workflow publishes with npm's trusted publishing, so it needs no token. Before its first release, a maintainer links the package to the workflow:
npm trust github @spindlecommerce/plugin-sentry --repo spindlecommerce/plugin-sentry --file release.yml --allow-stage-publishRun it just before tagging: npm drops a link that isn't used within 48 hours.
License
MIT
