@voltro/cli 0.60.0 → 0.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/apiBuild-5U7PxjLa.js +2 -0
- package/dist/{apiBuild-BU5cd-Fn.js → apiBuild-C5HhMAEm.js} +2 -2
- package/dist/bin.js +1 -1
- package/dist/{build-BxAsLzyU.js → build-DQr7SsKK.js} +7 -7
- package/dist/{checkCommand-C1CQc8lD.js → checkCommand-ByaOhdc8.js} +1 -1
- package/dist/{checkCommand-DC7k1_hP.js → checkCommand-CvSheSdb.js} +3 -3
- package/dist/{codegenCommand-kS3Twuc9.js → codegenCommand-CI0mpjxo.js} +1 -1
- package/dist/{codemodRunner-ClUqkhvR.js → codemodRunner-Drb-H-jr.js} +211 -161
- package/dist/{commands-Ro4hYBHD.js → commands-pCItjdHG.js} +21 -21
- package/dist/{dashboardCommand-t8Qsebjr.js → dashboardCommand-O-ToEgiH.js} +3 -3
- package/dist/{dataCommand-hNOGKz4K.js → dataCommand-mn1Zc88W.js} +1 -1
- package/dist/{dev-Ce2gEziv.js → dev-dSH-Pkb2.js} +1 -1
- package/dist/{dev-Dff_pdik.js → dev-kn9-7RXZ.js} +1 -1
- package/dist/doctorCommand-BVat2ejT.js +2 -0
- package/dist/{doctorCommand-CGjefPmk.js → doctorCommand-ClB7Ucz5.js} +13 -13
- package/dist/{dormancyCommand-DYgI0Kf-.js → dormancyCommand-DZupfuq-.js} +1 -1
- package/dist/{embeddingsCommand-yJivQSrI.js → embeddingsCommand-D8_GquVX.js} +1 -1
- package/dist/{envCommand-ORJUf8r_.js → envCommand-DRjVSXRp.js} +2 -2
- package/dist/{evolveCommand-CThb0EZZ.js → evolveCommand-Cb0C2b3V.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{infoCommand-a0WkKcUY.js → infoCommand-BlKnoY2D.js} +1 -1
- package/dist/{probeCommand-BUYzc0CT.js → probeCommand-DYsOFm62.js} +1 -1
- package/dist/{runtimeTrace-DDuKJgVi.js → runtimeTrace-BI3kdicc.js} +1 -1
- package/dist/{sdkgen-vq1fF9D_.js → sdkgen-DZ4zCtV4.js} +1 -1
- package/dist/serveCommand-CwK_6Wxt.js +2 -0
- package/dist/{serveCommand-Dr4KXmTS.js → serveCommand-DnxqCQ16.js} +3 -3
- package/dist/serveEntry.js +1 -1
- package/dist/{start-BhoDQ25C.js → start-DE4ixCTi.js} +1 -1
- package/dist/{start-CcdPRG8L.js → start-bqT4GRH0.js} +427 -418
- package/dist/startEntry.js +1 -1
- package/dist/{updateCommand-D9avpQFT.js → updateCommand-B18ZQNFg.js} +1 -1
- package/dist/updateCommand-B4EgDD-m.js +2 -0
- package/dist/{webDev-CBN9KkyQ.js → webDev-CYjhmOTZ.js} +1 -1
- package/dist/{webDev-Bzb8ZFus.js → webDev-CuG3Ged-.js} +1 -1
- package/dist/{webhooksCommand-BPJQOGTe.js → webhooksCommand-Bs-HZ4wY.js} +1 -1
- package/package.json +31 -19
- package/templates/AGENTS.md +2 -2
- package/templates/agent-docs/_index.md +2 -2
- package/templates/agent-docs/_manifest.json +1 -1
- package/templates/agent-docs/data.md +10 -2
- package/templates/agent-docs/observability.md +7 -1
- package/templates/agent-docs/plugins/sentry.md +29 -12
- package/templates/agent-docs/schema-driven-ui.md +38 -10
- package/templates/agent-docs/whats-new.md +10 -43
- package/templates/apps/api-ai/package.json +6 -6
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-sqlite/package.json +8 -8
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-cms/package.json +9 -9
- package/templates/apps/api-collab/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-row-history/package.json +8 -8
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-saas-starter/package.json +10 -10
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-status/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -9
- package/templates/apps/changelog/package.json +7 -7
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +7 -7
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-auth/package.json +7 -7
- package/templates/apps/frontend-blank/package.json +6 -6
- package/templates/apps/frontend-cms/package.json +8 -8
- package/templates/apps/frontend-collab/package.json +9 -9
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +6 -6
- package/templates/apps/frontend-docs/package.json +8 -8
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-portal/package.json +7 -7
- package/templates/apps/frontend-saas/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +6 -6
- package/templates/apps/frontend-ssr/package.json +6 -6
- package/templates/apps/frontend-ssr-api/package.json +7 -7
- package/templates/apps/frontend-static-blog/package.json +8 -8
- package/templates/apps/frontend-status/package.json +7 -7
- package/templates/apps/mobile-app/package.json +4 -4
- package/dist/apiBuild-B9OvhITV.js +0 -2
- package/dist/doctorCommand-DXnNpKQT.js +0 -2
- package/dist/serveCommand-1R52mo6F.js +0 -2
- package/dist/updateCommand-QMOirvXC.js +0 -2
package/dist/startEntry.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "./codemodRunner-
|
|
1
|
+
import { n as e, r as t, t as n } from "./codemodRunner-Drb-H-jr.js";
|
|
2
2
|
import { basename as r, dirname as i, join as a, relative as o, resolve as s } from "node:path";
|
|
3
3
|
import { existsSync as c, readFileSync as l, readdirSync as u, statSync as d, writeFileSync as f } from "node:fs";
|
|
4
4
|
import { totalmem as p } from "node:os";
|
|
@@ -2556,7 +2556,7 @@ The wrapper is what carries \`match\`, and what lets \`voltro doctor\` report wh
|
|
|
2556
2556
|
return [
|
|
2557
2557
|
"",
|
|
2558
2558
|
"// Browser-side Sentry (frontend half of the deep integration). Errors +",
|
|
2559
|
-
"//
|
|
2559
|
+
"// page-owned rpc spans linked to their server traces flow to Sentry.",
|
|
2560
2560
|
n === void 0 ? `await initSentryBrowser(${JSON.stringify(r)})` : `await initSentryBrowser({ ...${JSON.stringify(r)}, ...(await __sentryOptions()) })`
|
|
2561
2561
|
];
|
|
2562
2562
|
}, Fo = (e) => e.env ? ["import './env.public'"] : [], Io = (e) => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as e, T as t, m as n } from "./webDev-
|
|
1
|
+
import { C as e, T as t, m as n } from "./webDev-CYjhmOTZ.js";
|
|
2
2
|
export { n as loadConfig, e as tryRunWebServe, t as walkPagesTree };
|
|
@@ -222,7 +222,7 @@ createVerifier({ secret: [process.env.WEBHOOK_SECRET, process.env.WEBHOOK_SECRET
|
|
|
222
222
|
...t === void 0 ? {} : { payload: t }
|
|
223
223
|
};
|
|
224
224
|
}, S = u({ scope: "voltro:webhooks" }), C = ["--out", "--name"], w = async (e) => {
|
|
225
|
-
let { walk: t, loadDiscovered: n } = await import("./dev-
|
|
225
|
+
let { walk: t, loadDiscovered: n } = await import("./dev-kn9-7RXZ.js"), { outgoingFromEvents: r } = await import("./webhookDiscovery-il9ti-HE.js");
|
|
226
226
|
return r((await n(await t(e), { root: e })).events.map((e) => ({
|
|
227
227
|
file: e.file,
|
|
228
228
|
descriptor: e.descriptor
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.61.0",
|
|
4
4
|
"description": "The `voltro` CLI — dev server, codegen, migrations, project scaffolding, agent-docs seeding, and production serve.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -898,6 +898,18 @@
|
|
|
898
898
|
"title": "Sentry no longer reports declared failures by default",
|
|
899
899
|
"kind": "manual"
|
|
900
900
|
},
|
|
901
|
+
{
|
|
902
|
+
"version": "0.61.0",
|
|
903
|
+
"id": "0.61.0/01_rpc_errors_have_kinds",
|
|
904
|
+
"title": "`RpcError` now carries an explicit failure kind",
|
|
905
|
+
"kind": "manual"
|
|
906
|
+
},
|
|
907
|
+
{
|
|
908
|
+
"version": "0.61.0",
|
|
909
|
+
"id": "0.61.0/02_sentry_rpc_spans_join_page",
|
|
910
|
+
"title": "Sentry rpc spans now join the active browser transaction",
|
|
911
|
+
"kind": "manual"
|
|
912
|
+
},
|
|
901
913
|
{
|
|
902
914
|
"version": "0.7.0",
|
|
903
915
|
"id": "0.7.0/01_row-filter-load-failure",
|
|
@@ -944,24 +956,24 @@
|
|
|
944
956
|
"@effect/platform-node": "^0.108.0",
|
|
945
957
|
"@effect/sql": "^0.52.0",
|
|
946
958
|
"@effect/workflow": "^0.19.0",
|
|
947
|
-
"@voltro/ai": "0.
|
|
948
|
-
"@voltro/cache": "0.
|
|
949
|
-
"@voltro/client": "0.
|
|
950
|
-
"@voltro/content": "0.
|
|
951
|
-
"@voltro/data-transfer": "0.
|
|
952
|
-
"@voltro/database": "0.
|
|
953
|
-
"@voltro/env": "0.
|
|
954
|
-
"@voltro/kv": "0.
|
|
955
|
-
"@voltro/logger": "0.
|
|
956
|
-
"@voltro/plugin-auth": "0.
|
|
957
|
-
"@voltro/plugin-broadcast": "0.
|
|
958
|
-
"@voltro/plugin-mail": "0.
|
|
959
|
-
"@voltro/plugin-storage": "0.
|
|
960
|
-
"@voltro/plugin-webhooks": "0.
|
|
961
|
-
"@voltro/protocol": "0.
|
|
962
|
-
"@voltro/runtime": "0.
|
|
963
|
-
"@voltro/serverless": "0.
|
|
964
|
-
"@voltro/workflow": "0.
|
|
959
|
+
"@voltro/ai": "0.61.0",
|
|
960
|
+
"@voltro/cache": "0.61.0",
|
|
961
|
+
"@voltro/client": "0.61.0",
|
|
962
|
+
"@voltro/content": "0.61.0",
|
|
963
|
+
"@voltro/data-transfer": "0.61.0",
|
|
964
|
+
"@voltro/database": "0.61.0",
|
|
965
|
+
"@voltro/env": "0.61.0",
|
|
966
|
+
"@voltro/kv": "0.61.0",
|
|
967
|
+
"@voltro/logger": "0.61.0",
|
|
968
|
+
"@voltro/plugin-auth": "0.61.0",
|
|
969
|
+
"@voltro/plugin-broadcast": "0.61.0",
|
|
970
|
+
"@voltro/plugin-mail": "0.61.0",
|
|
971
|
+
"@voltro/plugin-storage": "0.61.0",
|
|
972
|
+
"@voltro/plugin-webhooks": "0.61.0",
|
|
973
|
+
"@voltro/protocol": "0.61.0",
|
|
974
|
+
"@voltro/runtime": "0.61.0",
|
|
975
|
+
"@voltro/serverless": "0.61.0",
|
|
976
|
+
"@voltro/workflow": "0.61.0",
|
|
965
977
|
"chokidar": "^5.0.0",
|
|
966
978
|
"ioredis": "^5.11.1",
|
|
967
979
|
"tinyglobby": "^0.2.17",
|
package/templates/AGENTS.md
CHANGED
|
@@ -749,7 +749,7 @@ each plugin's own README.
|
|
|
749
749
|
|
|
750
750
|
| Topic | Open | Summary |
|
|
751
751
|
|---|---|---|
|
|
752
|
-
| **What's new in 0.
|
|
752
|
+
| **What's new in 0.61.0** | `node_modules/@voltro/cli/templates/agent-docs/whats-new.md` | Everything that changed in this version. Read it before hand-rolling something the framework may now ship. |
|
|
753
753
|
| AI | `node_modules/@voltro/cli/templates/agent-docs/ai.md` | How Voltro treats AI — agents, tools, streaming, RAG — all primitives over the same WebSocket as the rest of the framework. |
|
|
754
754
|
| Authentication | `node_modules/@voltro/cli/templates/agent-docs/authentication.md` | How @voltro/plugin-auth wires password + session-cookie auth across api + web, plus the pluggable identity-strategy protocol. |
|
|
755
755
|
| Caching | `node_modules/@voltro/cli/templates/agent-docs/caching.md` | Voltro's caching layer (@voltro/cache) — an always-on memory default, swappable Redis-compatible backends, a low-level wrap primitive, and automatic query-result invalidation. |
|
|
@@ -832,7 +832,7 @@ each plugin's own README.
|
|
|
832
832
|
| row-history | `node_modules/@voltro/cli/templates/agent-docs/plugins/row-history.md` (or `node_modules/@voltro/plugin-row-history/README.md`) | Full row history + time-travel. audit() records who/when; row-history records what-changed-to-what — a value snapshot of every row on every write, with as-of queries. |
|
|
833
833
|
| scim | `node_modules/@voltro/cli/templates/agent-docs/plugins/scim.md` (or `node_modules/@voltro/plugin-scim/README.md`) | SCIM 2.0 provisioning — Users + Groups REST endpoints so an enterprise IdP (Okta, Entra, OneLogin) can create / update / deactivate users in your app. |
|
|
834
834
|
| search | `node_modules/@voltro/cli/templates/agent-docs/plugins/search.md` (or `node_modules/@voltro/plugin-search/README.md`) | Keep an external search index (Typesense / Meilisearch / Algolia) in sync with your tables via the ChangeEvent tap, query it tenant-scoped through a typed action + hook. |
|
|
835
|
-
| sentry | `node_modules/@voltro/cli/templates/agent-docs/plugins/sentry.md` (or `node_modules/@voltro/plugin-sentry/README.md`) | Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and
|
|
835
|
+
| sentry | `node_modules/@voltro/cli/templates/agent-docs/plugins/sentry.md` (or `node_modules/@voltro/plugin-sentry/README.md`) | Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and controlled performance traces. |
|
|
836
836
|
| soft-delete | `node_modules/@voltro/cli/templates/agent-docs/plugins/soft-delete.md` (or `node_modules/@voltro/plugin-soft-delete/README.md`) | The softDelete() schema mixin — deletedAt / deletedBy columns, delete() redirected to an UPDATE, default reads filtered, hardDelete() bypass. |
|
|
837
837
|
| sso-saml | `node_modules/@voltro/cli/templates/agent-docs/plugins/sso-saml.md` (or `node_modules/@voltro/plugin-sso-saml/README.md`) | Enterprise SAML 2.0 SSO — SP-initiated login, ACS assertion consumer, SP metadata. Signature verification via @node-saml/node-saml; framework session minting built in. |
|
|
838
838
|
| storage | `node_modules/@voltro/cli/templates/agent-docs/plugins/storage.md` (or `node_modules/@voltro/plugin-storage/README.md`) | File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / MinIO (R2 and GCS via their S3 interop) / Azure / database / filesystem / memory providers, presigned URLs, a dashboard browser. |
|
|
@@ -9,7 +9,7 @@ each plugin's own README.
|
|
|
9
9
|
|
|
10
10
|
| Topic | Open | Summary |
|
|
11
11
|
|---|---|---|
|
|
12
|
-
| **What's new in 0.
|
|
12
|
+
| **What's new in 0.61.0** | `node_modules/@voltro/cli/templates/agent-docs/whats-new.md` | Everything that changed in this version. Read it before hand-rolling something the framework may now ship. |
|
|
13
13
|
| AI | `node_modules/@voltro/cli/templates/agent-docs/ai.md` | How Voltro treats AI — agents, tools, streaming, RAG — all primitives over the same WebSocket as the rest of the framework. |
|
|
14
14
|
| Authentication | `node_modules/@voltro/cli/templates/agent-docs/authentication.md` | How @voltro/plugin-auth wires password + session-cookie auth across api + web, plus the pluggable identity-strategy protocol. |
|
|
15
15
|
| Caching | `node_modules/@voltro/cli/templates/agent-docs/caching.md` | Voltro's caching layer (@voltro/cache) — an always-on memory default, swappable Redis-compatible backends, a low-level wrap primitive, and automatic query-result invalidation. |
|
|
@@ -92,7 +92,7 @@ each plugin's own README.
|
|
|
92
92
|
| row-history | `node_modules/@voltro/cli/templates/agent-docs/plugins/row-history.md` (or `node_modules/@voltro/plugin-row-history/README.md`) | Full row history + time-travel. audit() records who/when; row-history records what-changed-to-what — a value snapshot of every row on every write, with as-of queries. |
|
|
93
93
|
| scim | `node_modules/@voltro/cli/templates/agent-docs/plugins/scim.md` (or `node_modules/@voltro/plugin-scim/README.md`) | SCIM 2.0 provisioning — Users + Groups REST endpoints so an enterprise IdP (Okta, Entra, OneLogin) can create / update / deactivate users in your app. |
|
|
94
94
|
| search | `node_modules/@voltro/cli/templates/agent-docs/plugins/search.md` (or `node_modules/@voltro/plugin-search/README.md`) | Keep an external search index (Typesense / Meilisearch / Algolia) in sync with your tables via the ChangeEvent tap, query it tenant-scoped through a typed action + hook. |
|
|
95
|
-
| sentry | `node_modules/@voltro/cli/templates/agent-docs/plugins/sentry.md` (or `node_modules/@voltro/plugin-sentry/README.md`) | Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and
|
|
95
|
+
| sentry | `node_modules/@voltro/cli/templates/agent-docs/plugins/sentry.md` (or `node_modules/@voltro/plugin-sentry/README.md`) | Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and controlled performance traces. |
|
|
96
96
|
| soft-delete | `node_modules/@voltro/cli/templates/agent-docs/plugins/soft-delete.md` (or `node_modules/@voltro/plugin-soft-delete/README.md`) | The softDelete() schema mixin — deletedAt / deletedBy columns, delete() redirected to an UPDATE, default reads filtered, hardDelete() bypass. |
|
|
97
97
|
| sso-saml | `node_modules/@voltro/cli/templates/agent-docs/plugins/sso-saml.md` (or `node_modules/@voltro/plugin-sso-saml/README.md`) | Enterprise SAML 2.0 SSO — SP-initiated login, ACS assertion consumer, SP metadata. Signature verification via @node-saml/node-saml; framework session minting built in. |
|
|
98
98
|
| storage | `node_modules/@voltro/cli/templates/agent-docs/plugins/storage.md` (or `node_modules/@voltro/plugin-storage/README.md`) | File storage behind one StorageService — public objects served direct from the bucket/CDN, private objects gated by an access policy + per-object grants. S3 / MinIO (R2 and GCS via their S3 interop) / Azure / database / filesystem / memory providers, presigned URLs, a dashboard browser. |
|
|
@@ -660,7 +660,7 @@
|
|
|
660
660
|
{
|
|
661
661
|
"slug": "sentry",
|
|
662
662
|
"title": "Sentry",
|
|
663
|
-
"description": "Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and
|
|
663
|
+
"description": "Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and controlled performance traces.",
|
|
664
664
|
"pkg": "@voltro/plugin-sentry",
|
|
665
665
|
"doc": "plugins/sentry.md",
|
|
666
666
|
"module": "agent-docs/plugins/sentry.md"
|
|
@@ -1220,13 +1220,21 @@ try {
|
|
|
1220
1220
|
}
|
|
1221
1221
|
```
|
|
1222
1222
|
|
|
1223
|
-
**Trace id for debugging.** An error caught from `useMutation` / `useAction`
|
|
1223
|
+
**Trace id for debugging.** An error caught from `useMutation` / `useAction`
|
|
1224
|
+
carries the **non-enumerable client-span id `__voltroTraceId`**:
|
|
1224
1225
|
|
|
1225
1226
|
```ts
|
|
1226
1227
|
const traceId = (err as { __voltroTraceId?: string }).__voltroTraceId
|
|
1227
|
-
//
|
|
1228
|
+
// If the server accepted the call: `voltro logs --trace <traceId>`
|
|
1228
1229
|
```
|
|
1229
1230
|
|
|
1231
|
+
For a declared handler error, the server necessarily accepted the call and the
|
|
1232
|
+
id joins to its span. For a transport error it may not: the connection can fail
|
|
1233
|
+
before the request arrived or after the handler ran but before its response
|
|
1234
|
+
returned. Use `kind` from
|
|
1235
|
+
[`useOnRpcError`](/docs/ui/client-utilities/use-on-rpc-error) for that distinction;
|
|
1236
|
+
the presence of the id alone proves only that the client span existed.
|
|
1237
|
+
|
|
1230
1238
|
`errorTag` lives in `@voltro/protocol` rather than in the client for a reason
|
|
1231
1239
|
worth knowing before you decide where your own error handling goes: **`_tag` is a
|
|
1232
1240
|
wire concept, and protocol owns the wire.** So a shared error handler in a package
|
|
@@ -213,6 +213,12 @@ Trace continuity is **automatic and on by default** in `voltro dev` — a buffer
|
|
|
213
213
|
- **api → api is automatic over HTTP.** An action or handler that calls another api via the framework `HttpClient` sends a W3C `traceparent` header; an inbound `*.webhook.tsx` route (an incoming HTTP handler) **continues** the caller's trace. So frontend → api Y → api Z (via webhook / HTTP) is **one** trace.
|
|
214
214
|
- **Every log line carries it.** Handlers stamp `fields.traceId` onto each log line they emit, so [`voltro logs --trace <id>`](/docs/observability/cli) returns the whole chain across hops, in order.
|
|
215
215
|
|
|
216
|
+
The client span exists before the transport proves delivery. If a connection
|
|
217
|
+
fails, its `traceId` can therefore have no matching server span — or the server
|
|
218
|
+
may have completed the handler and lost only the response. In rpc-error policy,
|
|
219
|
+
use [`RpcError.kind`](/docs/ui/client-utilities/use-on-rpc-error), never the mere
|
|
220
|
+
presence of `traceId`, to distinguish transport failures from handler failures.
|
|
221
|
+
|
|
216
222
|
```
|
|
217
223
|
client.mutation.placeOrder traceId=4bf92f35…
|
|
218
224
|
└─ mutation.placeOrder traceId=4bf92f35… (api Y, ctx.request.traceId)
|
|
@@ -259,7 +265,7 @@ This is the fastest way to answer "where did this error come from?" — far fast
|
|
|
259
265
|
|
|
260
266
|
The same trace continuity flows to a vendor APM when you install a deep-observability plugin — no `OTEL_*` env. Each contributes an OTel span-processor to the framework's tracer via `contributeObservability`, so the vendor runs as a **consumer** of the existing tracer (the in-app Traces panel keeps working) and receives the identical spans:
|
|
261
267
|
|
|
262
|
-
- [`@voltro/plugin-sentry`](/docs/plugins/sentry) — every mutation/query/action error becomes a Sentry issue correlated to its `trace_id` + `span_id`, with the request's log lines as breadcrumbs;
|
|
268
|
+
- [`@voltro/plugin-sentry`](/docs/plugins/sentry) — every mutation/query/action error becomes a Sentry issue correlated to its `trace_id` + `span_id`, with the request's log lines as breadcrumbs; server performance traces are on by default (`traces: false` disables them). The browser integration keeps rpc markers inside the sampled page/navigation transaction and links each marker to its Effect/server trace.
|
|
263
269
|
- [`@voltro/plugin-datadog`](/docs/plugins/datadog) — framework spans → the Datadog Agent's OTLP receiver (`traces: true`), plus log forwarding with `dd.trace_id` correlation.
|
|
264
270
|
|
|
265
271
|
See [Observability › Routing traces to a vendor](/docs/observability/overview#routing-traces-to-a-vendor) for the contribution surface + the sampler caveat.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sentry
|
|
2
2
|
|
|
3
|
-
> Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and
|
|
3
|
+
> Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and controlled performance traces.
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
<!-- source: en/plugins/sentry.md -->
|
|
10
10
|
## Sentry
|
|
11
11
|
|
|
12
|
-
_Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and
|
|
12
|
+
_Deep Sentry integration — errors correlated to the distributed trace, breadcrumbs from the log sink, and controlled performance traces._
|
|
13
13
|
|
|
14
|
-
`@voltro/plugin-sentry` is the deep Sentry integration: every mutation/query/action failure becomes a Sentry issue **correlated to the active distributed trace** (trace_id + span_id) and carrying the request's recent log lines as breadcrumbs.
|
|
14
|
+
`@voltro/plugin-sentry` is the deep Sentry integration: every mutation/query/action failure becomes a Sentry issue **correlated to the active distributed trace** (trace_id + span_id) and carrying the request's recent log lines as breadcrumbs. The framework's spans flow to Sentry as transactions by default.
|
|
15
15
|
|
|
16
16
|
Uses the official `@sentry/node` SDK in **OpenTelemetry-consumer mode** — it consumes the framework's existing tracer (it never becomes the global provider), so the in-app [Traces dashboard](/docs/observability/distributed-tracing) stays intact.
|
|
17
17
|
|
|
@@ -29,7 +29,7 @@ export default {
|
|
|
29
29
|
// dsn defaults to SENTRY_DSN; without a valid DSN the plugin is a no-op.
|
|
30
30
|
environment: 'production', // or SENTRY_ENVIRONMENT
|
|
31
31
|
release: '1.4.2', // or SENTRY_RELEASE
|
|
32
|
-
traces: true, // route the framework's spans → Sentry (default
|
|
32
|
+
traces: true, // route the framework's spans → Sentry (default on)
|
|
33
33
|
tracesSampleRate: 1.0,
|
|
34
34
|
profiling: true, // continuous CPU profiler via @sentry/profiling-node
|
|
35
35
|
}),
|
|
@@ -46,7 +46,7 @@ export default {
|
|
|
46
46
|
| `dsn` | `string` | `SENTRY_DSN` env | No valid DSN → the plugin is inert (no interceptors registered). |
|
|
47
47
|
| `environment` | `string` | `SENTRY_ENVIRONMENT` env | Sentry `environment` tag + `deployment.environment` resource attribute. |
|
|
48
48
|
| `release` | `string` | `SENTRY_RELEASE` env | Release-health + source-map matching; also `service.version`. |
|
|
49
|
-
| `traces` | `boolean` | `
|
|
49
|
+
| `traces` | `boolean` | `true` | Route the framework's OTel spans to Sentry as transactions. Off → errors + breadcrumbs only. |
|
|
50
50
|
| `tracesSampleRate` | `number` | `1.0` | Applied by the Sentry client (not a tracer sampler). Only relevant with `traces`. |
|
|
51
51
|
| `profiling` | `boolean` | `false` | Continuous CPU profiler via `@sentry/profiling-node` (lazy; warns if not installed). |
|
|
52
52
|
| `profilesSampleRate` | `number` | `1.0` | Only relevant with `profiling`. |
|
|
@@ -73,15 +73,15 @@ This guarantees the error links to its trace in Sentry **regardless** of the Eff
|
|
|
73
73
|
|
|
74
74
|
The framework log sink feeds a bounded **per-trace** ring (capped per-trace + LRU + TTL), keyed on each log line's `traceId`. On an error the trace's breadcrumbs are attached to the event; traces that never error are reaped by the TTL. So a Sentry issue shows the exact log lines leading up to it — for that request only.
|
|
75
75
|
|
|
76
|
-
##
|
|
76
|
+
## Server traces
|
|
77
77
|
|
|
78
78
|
The plugin contributes a `SentrySpanProcessor` to the framework's tracer (via the plugin observability surface — see [Observability › Routing traces to a vendor](/docs/observability/overview#routing-traces-to-a-vendor)). Every framework span becomes a Sentry transaction, sharing the same trace id the errors carry — so in Sentry you land on an error inside its full distributed trace.
|
|
79
79
|
|
|
80
80
|
We deliberately do **not** install a `SentrySampler` as the tracer's sampler: that would gate recording for the WHOLE tracer and blind the framework's own in-app Traces buffer. The framework keeps its always-on sampler; `tracesSampleRate` is applied by the Sentry client.
|
|
81
81
|
|
|
82
|
-
##
|
|
82
|
+
## Correlating the browser page with server traces
|
|
83
83
|
|
|
84
|
-
The plugin ships a browser half at `@voltro/plugin-sentry/web
|
|
84
|
+
The plugin ships a browser half at `@voltro/plugin-sentry/web`. It records one page-load or navigation transaction with rpc child spans, while each rpc child links to the Effect trace continued by the server. This avoids a transaction and network envelope per rpc call without losing the connection between browser and server work. Turn it on in the web app's `app.config.ts`:
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
87
|
// apps/web/app.config.ts
|
|
@@ -94,6 +94,8 @@ export default {
|
|
|
94
94
|
environment: 'production',
|
|
95
95
|
release: '1.4.2', // MUST match the api's `release` for unified release health
|
|
96
96
|
tracesSampleRate: 1.0,
|
|
97
|
+
browserTracing: true,
|
|
98
|
+
rpcSpans: true,
|
|
97
99
|
},
|
|
98
100
|
}
|
|
99
101
|
```
|
|
@@ -102,7 +104,22 @@ The framework's generated entry calls `initSentryBrowser()` before mount (no cod
|
|
|
102
104
|
|
|
103
105
|
What it does:
|
|
104
106
|
- **Inits `@sentry/react`** with `browserTracingIntegration` — page loads + client navigations become Sentry transactions, and unhandled errors / promise rejections are captured by the SDK's default global handlers.
|
|
105
|
-
- **
|
|
107
|
+
- **Keeps rpc spans page-owned.** Every framework rpc call (`useMutation`/`useSubscription`/`useAction`) already wraps itself in an Effect client span and propagates that span's W3C `traceId`+`spanId` to the api. The browser half adds a child to the currently active page/navigation transaction and attaches the Effect/server trace as a span link. If no browser transaction is active, it emits no rpc root transaction.
|
|
108
|
+
- **Honours sampling.** `tracesSampleRate` decides whether the page/navigation root is recorded; its rpc children inherit that decision. The bridge does not inject a sampled parent decision.
|
|
109
|
+
|
|
110
|
+
Browser trace controls:
|
|
111
|
+
|
|
112
|
+
| Option | Default | Effect |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `tracesSampleRate` | `1.0` | Samples page-load/navigation transactions and therefore their rpc children. Error reporting is independent. |
|
|
115
|
+
| `browserTracing` | `true` | Installs page-load/navigation instrumentation. `false` also defaults `rpcSpans` to off. |
|
|
116
|
+
| `rpcSpans` | same as `browserTracing` | Adds rpc children to an active browser transaction. `false` keeps browser errors and page traces but removes the rpc bridge. Set it to `true` with `browserTracing:false` only if your app creates active Sentry transactions itself. |
|
|
117
|
+
|
|
118
|
+
At browser boot the plugin prints the effective values, including the mode:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
[@voltro/plugin-sentry] browser active { tracesSampleRate: 1, browserTracing: true, rpcSpans: true, rpcSpanMode: 'page-child-with-server-link' }
|
|
122
|
+
```
|
|
106
123
|
|
|
107
124
|
> **Manual wiring** (no app.config field, e.g. an app that builds its own entry): call it yourself once at boot —
|
|
108
125
|
> ```ts
|
|
@@ -157,9 +174,9 @@ in deployment env. Setting one as a deployment variable deploys cleanly and does
|
|
|
157
174
|
nothing; `voltro start` warns when it finds one, naming whether the bundle
|
|
158
175
|
carries that key at all.
|
|
159
176
|
|
|
160
|
-
The two halves are independent: the api plugin alone gives you server traces + errors; add the web half for
|
|
177
|
+
The two halves are independent: the api plugin alone gives you server traces + errors; add the web half for page performance, browser errors, rpc markers, and links back to the server traces. Both tracing halves are on by default, so an app with the plugin on the api and `@voltro/plugin-sentry` as a dependency of the web app gets server transactions plus one sampled browser transaction per page/navigation from one `SENTRY_DSN` plus one `VOLTRO_PUBLIC_SENTRY_DSN`. Give both halves the same `release`.
|
|
161
178
|
|
|
162
|
-
**Traces default to on, at `tracesSampleRate: 1.0`.** That is
|
|
179
|
+
**Traces default to on, at `tracesSampleRate: 1.0`.** That is explicit, not a production recommendation. Lower the rate independently on api and web to fit the trace budget. Set api `traces:false` to keep server errors and breadcrumbs only; set web `browserTracing:false` to keep browser error capture without automatic performance transactions; or use web `rpcSpans:false` to keep page performance while omitting rpc child spans.
|
|
163
180
|
|
|
164
181
|
## Source maps (every bundle, browser and server)
|
|
165
182
|
|
|
@@ -344,7 +361,7 @@ Once the two halves are wired, most errors are captured **with no per-call code*
|
|
|
344
361
|
| rpc handler throw (mutation/query/action) | ✅ auto | server interceptor → Sentry, trace-correlated + breadcrumbs |
|
|
345
362
|
| Unhandled browser error / promise rejection | ✅ auto | `@sentry/react` global handlers (after `initSentryBrowser`) |
|
|
346
363
|
| **React render error, in the BROWSER** (any page, incl. catch-all `[...slug]`, `error.tsx` boundary) | ✅ auto | the framework's route ErrorBoundary publishes to a client-error bus → the Sentry web bridge captures it. React swallows boundary-caught errors before `window.onerror`, so this bridge is what makes them reach Sentry — tagged with the route + component stack. |
|
|
347
|
-
| **React render error, during SSR**
|
|
364
|
+
| **React render error, during SSR** — six sites: `ssr-shell`, `spa-layout-shell`, `render` (incl. a loader throw), `not-found-render`, `ppr-holes`, `swr-refresh` | ✅ auto, from the WEB server | a different process and a different path: the render never reaches a browser, so the row above cannot cover it. Captured by the web server's own Sentry (see the section above), tagged `voltro.process=web` and `voltro.stage`. The last three are `warn`-level — the request still serves something — and are reported anyway: quieter is not less real, and nothing else can see them. Needs `SENTRY_DSN` on the **web** deployment. |
|
|
348
365
|
| **Loader failure** (page/layout `loader` reject) | ✅ auto | same route bus path |
|
|
349
366
|
| Manual try/catch (event handler, async effect, anywhere) | ✋ one call | `reportClientError(error, context?)` |
|
|
350
367
|
| **Every other server primitive** — REST route (`defineRestRoute`), aggregate, subscriber, schedule, workflow, webhook, startup | ✅ auto | each primitive's error path publishes to the framework's server-error bus → the plugin captures it, tagged `voltro.errorSource` + `voltro.name` (+ traceId for workflows) |
|
|
@@ -1194,10 +1194,20 @@ const { status, reportSuccess } = useConnectionStatus('app')
|
|
|
1194
1194
|
`status` is `'connected' | 'degraded' | 'offline'`. `offline` is browser-reported
|
|
1195
1195
|
(`navigator.onLine` plus its `online` / `offline` events) — reliable for "the
|
|
1196
1196
|
network is gone", and it wins over `degraded`. `degraded` means an rpc on that
|
|
1197
|
-
api failed
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1197
|
+
api failed with `kind: 'transport'` and no later call has proved the server
|
|
1198
|
+
reachable. Declared handler errors do **not** colour the connection; if already
|
|
1199
|
+
degraded, a handler reply clears it because the server demonstrably answered.
|
|
1200
|
+
Local client and unknown failures leave the connection state unchanged. Any rpc
|
|
1201
|
+
success also clears the failure count automatically. Coming back online clears
|
|
1202
|
+
it too, since failures counted during an offline window *are* that window.
|
|
1203
|
+
`reportSuccess()` remains the explicit escape hatch for another signal that
|
|
1204
|
+
proves a round trip succeeded.
|
|
1205
|
+
|
|
1206
|
+
Use this hook to **render aggregate connection state**. To classify the failure
|
|
1207
|
+
that is firing right now — for example, to avoid a data-error toast in the same
|
|
1208
|
+
tick the socket drops — branch on `event.kind` inside
|
|
1209
|
+
[`useOnRpcError`](/docs/ui/client-utilities/use-on-rpc-error). React state updates
|
|
1210
|
+
after the event and therefore cannot classify that event retroactively.
|
|
1201
1211
|
|
|
1202
1212
|
Also returned: `online`, `failureCount`, `lastFailureAt`. There is deliberately
|
|
1203
1213
|
no polling ping — the framework does not call the server just to colour an
|
|
@@ -1578,16 +1588,34 @@ import { useOnRpcError } from '@voltro/client'
|
|
|
1578
1588
|
import { errorTag } from '@voltro/protocol'
|
|
1579
1589
|
|
|
1580
1590
|
useOnRpcError('app', useCallback((e) => {
|
|
1591
|
+
if (e.kind === 'transport') {
|
|
1592
|
+
showConnectionLost()
|
|
1593
|
+
return
|
|
1594
|
+
}
|
|
1581
1595
|
if (errorTag(e.error) === 'Unauthenticated') redirectToSignIn()
|
|
1582
1596
|
}, []))
|
|
1583
1597
|
```
|
|
1584
1598
|
|
|
1585
|
-
The event is `{ source, tag, error, traceId? }`. `source` is
|
|
1599
|
+
The event is `{ source, tag, error, kind, traceId? }`. `source` is
|
|
1586
1600
|
`'mutation' | 'action' | 'subscription'`, so both unary calls and stream
|
|
1587
1601
|
failures arrive here. `error` is the raw value — a `Schema.TaggedError`, a plain
|
|
1588
1602
|
`Error`, or anything else that was thrown; `errorTag(err)` reads `_tag` off
|
|
1589
|
-
tagged errors and returns `undefined` otherwise.
|
|
1590
|
-
|
|
1603
|
+
tagged errors and returns `undefined` otherwise.
|
|
1604
|
+
|
|
1605
|
+
`kind` is `'transport' | 'handler' | 'client' | 'unknown'`:
|
|
1606
|
+
|
|
1607
|
+
- `transport` — @effect/rpc could not complete the exchange. Use this branch for
|
|
1608
|
+
connection banners and to suppress misleading data-error toasts.
|
|
1609
|
+
- `handler` — the rpc returned a declared failure, such as `Unauthenticated`.
|
|
1610
|
+
- `client` — framework work around the call failed locally.
|
|
1611
|
+
- `unknown` — a combined or opaque operation could not be classified honestly.
|
|
1612
|
+
|
|
1613
|
+
`traceId` identifies the **client call span**. When the server accepted the
|
|
1614
|
+
request, it propagates the same id and `voltro logs --trace <id>` can join the
|
|
1615
|
+
call to server logs. A transport error can happen before the server saw the
|
|
1616
|
+
request, or after it handled the request but before the response returned, so a
|
|
1617
|
+
`traceId` on `kind: 'transport'` is not proof that server logs exist. For the
|
|
1618
|
+
same reason the event deliberately has no `reachedServer` boolean.
|
|
1591
1619
|
|
|
1592
1620
|
Two things to know. The hook re-subscribes whenever the listener **reference**
|
|
1593
1621
|
changes, so define it with `useCallback` or at module scope unless you want that.
|
|
@@ -1598,9 +1626,9 @@ per api name.
|
|
|
1598
1626
|
is also published on the client error bus, so a reporter — the Sentry browser
|
|
1599
1627
|
integration, or anything wired with `subscribeClientErrors` — already sees it,
|
|
1600
1628
|
under `source: 'rpc.mutation' | 'rpc.action' | 'rpc.subscription'` with the rpc
|
|
1601
|
-
tag and `traceId` in `context`. This hook is for
|
|
1602
|
-
on `Unauthenticated`, toast on a network
|
|
1603
|
-
the two by hand now reports twice.
|
|
1629
|
+
tag, `rpcErrorKind`, and optional `traceId` in `context`. This hook is for
|
|
1630
|
+
cross-cutting *policy* (redirect on `Unauthenticated`, toast on a network
|
|
1631
|
+
failure), not for telemetry; bridging the two by hand now reports twice.
|
|
1604
1632
|
|
|
1605
1633
|
Everything is published, including a reconnect storm. If that is too loud for
|
|
1606
1634
|
your reporter, gate it in the subscriber — which failures are worth an event is
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# What's new in 0.
|
|
1
|
+
# What's new in 0.61.0
|
|
2
2
|
|
|
3
3
|
Read this FIRST when a task touches an area you have not worked in recently.
|
|
4
4
|
It is the cheapest way to notice that the framework grew the thing you were
|
|
@@ -9,54 +9,21 @@ BREAKING entries name a codemod; run `voltro update` to apply it.
|
|
|
9
9
|
|
|
10
10
|
### ⚠ BREAKING
|
|
11
11
|
|
|
12
|
-
- **@voltro/
|
|
12
|
+
- **@voltro/client, @voltro/web, @voltro/cli** — `RpcError.kind` now distinguishes transport, handler, client, and unknown failures; manually emitted events must add the field, while `useConnectionStatus` now degrades only for transport failures and clears on the next rpc success.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
**`voltro update` carries you across this** — codemod `0.61.0/01_rpc_errors_have_kinds`. If you pin versions by hand and never run it, print the notes without changing anything: `voltro update --codemods-only --from <your current version> --dry-run` (this one ships in 0.61.0).
|
|
15
|
+
- **@voltro/plugin-sentry, @voltro/cli** — Browser RPC spans now join the active page/navigation transaction and link to the Effect/server trace instead of creating one root transaction per call; `tracesSampleRate`, `browserTracing`, and the new `rpcSpans` switch control the resulting browser trace volume.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
`shouldCapture` now skips a cause that is failures-ONLY. A defect is reported as before, including a defect that travelled beside a failure — the rule is failures-only rather than "any failure present" precisely so one cannot hide the other. `captureFailures: true` restores the old behaviour; a predicate keeps the ones that are signal.
|
|
19
|
-
|
|
20
|
-
**The browser half moved with it**, or the option would have been half-wired: a rejected call is an rpc error on the client too, published to the client error bus and captured by the browser bridge. `initSentryBrowser` takes the same option and applies it to `rpc.*` events carrying a `_tag`. Route render failures and `reportClientError` calls are never filtered — nobody declared those.
|
|
21
|
-
|
|
22
|
-
**2. `sentry-cli sourcemaps upload` does NOT write debug ids.** `inject` is a separate subcommand; `upload` only uses ids that are already present, and falls back to matching on the artifact NAME when they are not. That fallback cannot work for a server bundle: the artifact is named from `--url-prefix` (`~/chunk- ABC.js`) while the frame carries the absolute path the node process loaded, and nothing rewrites either side.
|
|
23
|
-
|
|
24
|
-
Measured downstream: 4300 artifacts uploaded, release finalised, every frame still minified. Nothing was red — the exact shape this code's own header warns about, an upload that matched nothing looking like one that worked. The comment above the uploader asserted the injection happened, which made it a description standing where a check belonged.
|
|
25
|
-
|
|
26
|
-
`inject` now runs first, over the same directories, and `sourcemapDebugIds.test.ts` drives the real binary to assert an id lands in both the JS and the map. `--url-prefix` stays as the fallback for the browser bundle, whose frames really are URLs.
|
|
27
|
-
|
|
28
|
-
The boot line names the new setting (`sentry active … captureFailures=false`), because a default the framework picks for you is one nobody finds again.
|
|
29
|
-
|
|
30
|
-
**`voltro update` carries you across this** — codemod `0.60.0/01_declared_failures_are_not_incidents`. If you pin versions by hand and never run it, print the notes without changing anything: `voltro update --codemods-only --from <your current version> --dry-run` (this one ships in 0.60.0).
|
|
31
|
-
|
|
32
|
-
### Added
|
|
33
|
-
|
|
34
|
-
- **@voltro/cli, @voltro/plugin-sentry** — **The web server process now initialises Sentry and reports its own errors.**
|
|
35
|
-
|
|
36
|
-
A framework app runs two server processes. `voltro serve` is the api, where `sentryPlugin()` initialises the SDK through the plugin lifecycle. `voltro start` is the web server — SSR, loaders, ISR, the revalidation legs — and it has no plugin lifecycle, so it had none.
|
|
37
|
-
|
|
38
|
-
That was not a cosmetic difference in boot output. A web pod legitimately logs less than an api pod, because it has no store, no rpc, no scheduler, no workflows and no plugins. What it also had was **no error reporting**: an SSR shell throw is caught, logged and answered with a 500, so no browser ever renders it and the client-side ErrorBoundary bridge cannot see it either. Both ends of the integration worked and the middle was dark — while the docs' "React render error ✅ auto" row, true of the client path, read as covering all of them.
|
|
39
|
-
|
|
40
|
-
Set `SENTRY_DSN` on the web deployment and the boot says `sentry active` with the same message and the same field names as the api half, from the same function — `initSentryServer` in `@voltro/plugin-sentry/server`, which the api plugin now calls too. One init, because a copy of `skipOpenTelemetrySetup`, the traces default, the overrides-first spread and the degrade-on-missing-SDK path would have drifted the moment either half gained a case.
|
|
41
|
-
|
|
42
|
-
Three deliberate asymmetries, each because the two processes are not the same thing:
|
|
43
|
-
|
|
44
|
-
- **`traces: false` on the web side.** The api contributes a span processor to the framework's tracer; the web server has no tracer at all, so tracing on would put `traces: true` in a boot line while nothing produces a span. - **No DSN is SILENT here.** On the api side `sentryPlugin()` is a declaration and an inert one contradicts it. There is no declaration here. - **`@voltro/plugin-sentry` must be installed in the WEB app.** With a DSN set and the package missing, the boot names the command rather than failing — monitoring must never be what stops a deploy.
|
|
45
|
-
|
|
46
|
-
Measured against a real production `voltro start`, both branches. Note that production `voltro start` loads the app's precompiled start bundle, so a web deployment picks this up when that bundle is rebuilt — the framework version alone is not enough.
|
|
17
|
+
**`voltro update` carries you across this** — codemod `0.61.0/02_sentry_rpc_spans_join_page`. If you pin versions by hand and never run it, print the notes without changing anything: `voltro update --codemods-only --from <your current version> --dry-run` (this one ships in 0.61.0).
|
|
47
18
|
|
|
48
19
|
### Fixed
|
|
49
20
|
|
|
50
|
-
- **@voltro/
|
|
51
|
-
|
|
52
|
-
A pod tail showed `[voltro:workflow] shard-lock coordination: row-based (dialect=mariadb, mode=row)` sitting between JSON records. `@voltro/logger` is what makes a line JSON in a pod and pretty on a TTY; a `process.stderr.write` bypasses that decision at exactly the place nobody looks, because a dev terminal renders both the same.
|
|
53
|
-
|
|
54
|
-
Fixed at the source: the workflow cluster layer (2), `rpcServer`'s computed-cache warning, the subscription outbox's and the RYW store's `warn`/`onError` defaults — those two are not fallbacks, the callers pass nothing, so the default IS the production path — and the migration file discovery's skip notice, which lands in the migrate job's stream.
|
|
21
|
+
- **@voltro/cli** — **Six SSR failure sites report to Sentry, not three.**
|
|
55
22
|
|
|
56
|
-
|
|
23
|
+
0.60.0 gave the web server its own Sentry and wired the three loud sites: the SSR shell throw, the SPA layout shell throw, and the general render error (which covers a loader throw). The docs said "shell throw, loader throw, PPR/SWR refresh" — and an enumeration in a claim is read as exhaustive.
|
|
57
24
|
|
|
58
|
-
|
|
25
|
+
The other three were `warn`-level and reported to nobody: a failed PPR hole pass, a failed background SWR refresh, and a `not-found.tsx` that throws while rendering. They are quieter because the request still serves something — stale HTML, an unfilled hole, a plain 404 — which says something about the REQUEST and nothing about who else could find out. The answer to that is nobody: none of them reaches a browser boundary, so the pod's stdout was the only record.
|
|
59
26
|
|
|
60
|
-
|
|
27
|
+
They carry their own `voltro.stage` (`not-found-render`, `ppr-holes`, `swr-refresh`), so a quota-conscious project can drop them by stage without losing the three that fail the request.
|
|
61
28
|
|
|
62
|
-
|
|
29
|
+
`webSentry.test.ts` now fails if a render-path `log.error`/`log.warn` gains no reporter beside it — the property, rather than the six call sites.
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@effect/platform": "^0.97.0",
|
|
14
14
|
"@effect/rpc": "^0.76.0",
|
|
15
|
-
"@voltro/ai": "0.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/protocol": "0.
|
|
20
|
-
"@voltro/runtime": "0.
|
|
15
|
+
"@voltro/ai": "0.61.0",
|
|
16
|
+
"@voltro/cli": "0.61.0",
|
|
17
|
+
"@voltro/database": "0.61.0",
|
|
18
|
+
"@voltro/env": "0.61.0",
|
|
19
|
+
"@voltro/protocol": "0.61.0",
|
|
20
|
+
"@voltro/runtime": "0.61.0",
|
|
21
21
|
"effect": "^3.22.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-auth": "0.
|
|
20
|
-
"@voltro/protocol": "0.
|
|
21
|
-
"@voltro/runtime": "0.
|
|
22
|
-
"@voltro/sql-postgres": "0.
|
|
16
|
+
"@voltro/cli": "0.61.0",
|
|
17
|
+
"@voltro/database": "0.61.0",
|
|
18
|
+
"@voltro/env": "0.61.0",
|
|
19
|
+
"@voltro/plugin-auth": "0.61.0",
|
|
20
|
+
"@voltro/protocol": "0.61.0",
|
|
21
|
+
"@voltro/runtime": "0.61.0",
|
|
22
|
+
"@voltro/sql-postgres": "0.61.0",
|
|
23
23
|
"effect": "^3.22.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/testing": "0.
|
|
26
|
+
"@voltro/testing": "0.61.0",
|
|
27
27
|
"typescript": "^6.0.3",
|
|
28
28
|
"@vitest/coverage-v8": "^4.1.10",
|
|
29
29
|
"vitest": "^4.1.10"
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@effect/platform": "^0.97.0",
|
|
18
18
|
"@effect/rpc": "^0.76.0",
|
|
19
|
-
"@voltro/cli": "0.
|
|
20
|
-
"@voltro/database": "0.
|
|
21
|
-
"@voltro/env": "0.
|
|
22
|
-
"@voltro/plugin-multitenancy": "0.
|
|
23
|
-
"@voltro/protocol": "0.
|
|
24
|
-
"@voltro/runtime": "0.
|
|
19
|
+
"@voltro/cli": "0.61.0",
|
|
20
|
+
"@voltro/database": "0.61.0",
|
|
21
|
+
"@voltro/env": "0.61.0",
|
|
22
|
+
"@voltro/plugin-multitenancy": "0.61.0",
|
|
23
|
+
"@voltro/protocol": "0.61.0",
|
|
24
|
+
"@voltro/runtime": "0.61.0",
|
|
25
25
|
"effect": "^3.22.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@voltro/testing": "0.
|
|
28
|
+
"@voltro/testing": "0.61.0",
|
|
29
29
|
"typescript": "^6.0.3",
|
|
30
30
|
"@vitest/coverage-v8": "^4.1.10",
|
|
31
31
|
"vitest": "^4.1.10"
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@effect/platform": "^0.97.0",
|
|
15
15
|
"@effect/rpc": "^0.76.0",
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/database": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/plugin-deactivation": "0.
|
|
20
|
-
"@voltro/protocol": "0.
|
|
21
|
-
"@voltro/runtime": "0.
|
|
16
|
+
"@voltro/cli": "0.61.0",
|
|
17
|
+
"@voltro/database": "0.61.0",
|
|
18
|
+
"@voltro/env": "0.61.0",
|
|
19
|
+
"@voltro/plugin-deactivation": "0.61.0",
|
|
20
|
+
"@voltro/protocol": "0.61.0",
|
|
21
|
+
"@voltro/runtime": "0.61.0",
|
|
22
22
|
"effect": "^3.22.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/testing": "0.
|
|
25
|
+
"@voltro/testing": "0.61.0",
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
27
|
"@vitest/coverage-v8": "^4.1.10",
|
|
28
28
|
"vitest": "^4.1.10"
|