@autter/runtime-next 1.8.0 → 1.9.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/README.md CHANGED
@@ -230,6 +230,44 @@ export const POST = withRuntimeRequest(async (request) => {
230
230
  }, { name: "checkout" });
231
231
  ```
232
232
 
233
+ `withAutter(handler)` is `withRuntimeRequest` that also **answers** a thrown
234
+ error: it records it with its stack and replies with the error's own status,
235
+ so a thrown 4xx stays a 4xx (not an anonymous 500), while Next's `redirect()`
236
+ and `notFound()` pass through untouched and are never reported.
237
+
238
+ ```ts
239
+ // app/api/orders/[id]/route.ts
240
+ import { withAutter, RuntimeError } from "@autter/runtime-next";
241
+
242
+ export const GET = withAutter(async (request, { params }) => {
243
+ const order = await findOrder(params.id);
244
+ if (!order) throw new RuntimeError({ status: 404, code: "orders.not_found", message: "No such order" });
245
+ return Response.json(order); // a thrown 404 is recorded and answered as 404
246
+ });
247
+ ```
248
+
249
+ Next.js error pages report through Autter too (RF-04). In a client
250
+ `app/error.tsx`, call `useAutterErrorReport(error)`; for
251
+ `app/global-error.tsx`, export the ready `AutterGlobalError`, or call
252
+ `reportNextError(error, { boundary: "global-error" })`. Each reports once per
253
+ error, with the boundary and Next's `digest`, through the browser tracker
254
+ (`@autter/runtime-next/client`):
255
+
256
+ ```tsx
257
+ "use client";
258
+ import { useAutterErrorReport } from "@autter/runtime-next/client";
259
+ export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
260
+ useAutterErrorReport(error);
261
+ return <button onClick={reset}>Try again</button>;
262
+ }
263
+ ```
264
+
265
+ Caught errors count on the server (`console.error`, pino/winston/bunyan,
266
+ `runtimeLogger.error`) and in the browser (`console.error`) by default, and
267
+ `runtimeContext.degraded(err, reason)` marks a deliberate fallback — see the
268
+ [runtime-node](../runtime-node) and [runtime-browser](../runtime-browser)
269
+ READMEs.
270
+
233
271
  Everything new in `@autter/runtime-node` 1.5.0 (`runtimeContext`,
234
272
  `RuntimeError`, `defineRuntimeErrors`, `runInBackground`, `initAutterLogging`,
235
273
  enrichers, sinks, …) is re-exported from `@autter/runtime-next` and
@@ -2,13 +2,14 @@
2
2
  import {
3
3
  createBrowserRelayFetchHandler,
4
4
  initAutterServer,
5
+ runtimeContext,
5
6
  withRuntimeRequest as nodeWithRuntimeRequest
6
7
  } from "@autter/runtime-node";
7
8
 
8
9
  // package.json
9
10
  var package_default = {
10
11
  name: "@autter/runtime-next",
11
- version: "1.8.0",
12
+ version: "1.9.0",
12
13
  description: "One-command Autter Runtime for Next.js: server OTel, request wide events, coded errors, browser tracker, relay route, edge middleware and React error boundary",
13
14
  license: "MIT",
14
15
  type: "module",
@@ -63,9 +64,9 @@ var package_default = {
63
64
  test: "npm run build -w @autter/runtime-core && npm run build -w @autter/runtime-node && npm run build -w @autter/runtime-edge && npm run build -w @autter/runtime-browser && npm run build && node --test test/*.test.mjs"
64
65
  },
65
66
  dependencies: {
66
- "@autter/runtime-browser": "^1.7.0",
67
- "@autter/runtime-edge": "^1.2.0",
68
- "@autter/runtime-node": "^1.8.0"
67
+ "@autter/runtime-browser": "^1.8.0",
68
+ "@autter/runtime-edge": "^1.4.0",
69
+ "@autter/runtime-node": "^1.9.0"
69
70
  },
70
71
  peerDependencies: {
71
72
  react: ">=18"
@@ -94,6 +95,20 @@ var package_default = {
94
95
  ]
95
96
  };
96
97
 
98
+ // src/control-flow.ts
99
+ var CONTROL_FLOW_DIGEST = /^(?:NEXT_REDIRECT|NEXT_NOT_FOUND|NEXT_HTTP_ERROR_FALLBACK|DYNAMIC_SERVER_USAGE|BAILOUT_TO_CLIENT_SIDE_RENDERING)\b/;
100
+ function digestOf(error) {
101
+ try {
102
+ const digest = error?.digest;
103
+ return typeof digest === "string" ? digest : "";
104
+ } catch {
105
+ return "";
106
+ }
107
+ }
108
+ function isNextControlFlow(error) {
109
+ return CONTROL_FLOW_DIGEST.test(digestOf(error));
110
+ }
111
+
97
112
  // src/server.ts
98
113
  import {
99
114
  createRuntimeLogger,
@@ -112,7 +127,7 @@ import {
112
127
  makeSafeCapture,
113
128
  installAutterAutoFlush,
114
129
  redactAttributes,
115
- runtimeContext,
130
+ runtimeContext as runtimeContext2,
116
131
  runInBackground,
117
132
  autterRequests,
118
133
  autterFastify,
@@ -178,11 +193,30 @@ function withRuntimeRequest(handler, options = {}) {
178
193
  waitUntil: options.waitUntil ?? scheduleAfter
179
194
  });
180
195
  }
196
+ function withAutter(handler, options = {}) {
197
+ const rule = options.capture;
198
+ return withRuntimeRequest(
199
+ async (request, ...rest) => {
200
+ try {
201
+ return await handler(request, ...rest);
202
+ } catch (error) {
203
+ if (isNextControlFlow(error)) runtimeContext.outcome("succeeded");
204
+ throw error;
205
+ }
206
+ },
207
+ {
208
+ ...options,
209
+ capture: (error) => !isNextControlFlow(error) && (typeof rule === "function" ? rule(error) === true : rule !== false),
210
+ errorResponse: (error) => !isNextControlFlow(error)
211
+ }
212
+ );
213
+ }
181
214
 
182
215
  export {
183
216
  registerAutter,
184
217
  createAutterRelayRoute,
185
218
  withRuntimeRequest,
219
+ withAutter,
186
220
  createRuntimeLogger,
187
221
  runtimeLogger,
188
222
  withRuntimeOperation,
@@ -199,7 +233,7 @@ export {
199
233
  makeSafeCapture,
200
234
  installAutterAutoFlush,
201
235
  redactAttributes,
202
- runtimeContext,
236
+ runtimeContext2 as runtimeContext,
203
237
  runInBackground,
204
238
  autterRequests,
205
239
  autterFastify,
@@ -1,5 +1,7 @@
1
1
  // src/request-error.ts
2
2
  import { captureEdgeException } from "@autter/runtime-edge";
3
+
4
+ // src/control-flow.ts
3
5
  var CONTROL_FLOW_DIGEST = /^(?:NEXT_REDIRECT|NEXT_NOT_FOUND|NEXT_HTTP_ERROR_FALLBACK|DYNAMIC_SERVER_USAGE|BAILOUT_TO_CLIENT_SIDE_RENDERING)\b/;
4
6
  function digestOf(error) {
5
7
  try {
@@ -9,6 +11,11 @@ function digestOf(error) {
9
11
  return "";
10
12
  }
11
13
  }
14
+ function isNextControlFlow(error) {
15
+ return CONTROL_FLOW_DIGEST.test(digestOf(error));
16
+ }
17
+
18
+ // src/request-error.ts
12
19
  function shouldReport(error, rule) {
13
20
  if (rule === true) return true;
14
21
  if (rule === false) return false;
@@ -19,7 +26,7 @@ function shouldReport(error, rule) {
19
26
  return false;
20
27
  }
21
28
  }
22
- return !CONTROL_FLOW_DIGEST.test(digestOf(error));
29
+ return !isNextControlFlow(error);
23
30
  }
24
31
  function requestErrorAttributes(error, request, context) {
25
32
  const out = {};
package/dist/client.cjs CHANGED
@@ -34,25 +34,28 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
34
34
  var client_exports = {};
35
35
  __export(client_exports, {
36
36
  AutterErrorBoundary: () => AutterErrorBoundary,
37
+ AutterGlobalError: () => AutterGlobalError,
37
38
  addBreadcrumb: () => import_breadcrumbs.addBreadcrumb,
38
- autterErrorFromResponse: () => import_runtime_browser2.autterErrorFromResponse,
39
- captureException: () => import_runtime_browser2.captureException,
40
- captureMessage: () => import_runtime_browser2.captureMessage,
41
- captureOutcome: () => import_runtime_browser2.captureOutcome,
39
+ autterErrorFromResponse: () => import_runtime_browser3.autterErrorFromResponse,
40
+ captureException: () => import_runtime_browser3.captureException,
41
+ captureMessage: () => import_runtime_browser3.captureMessage,
42
+ captureOutcome: () => import_runtime_browser3.captureOutcome,
42
43
  clearBreadcrumbs: () => import_breadcrumbs.clearBreadcrumbs,
43
44
  createFilter: () => import_filters.createFilter,
44
45
  disableTracePropagation: () => import_tracing.disableTracePropagation,
45
46
  enableBreadcrumbs: () => import_breadcrumbs.enableBreadcrumbs,
46
47
  enableTracePropagation: () => import_tracing.enableTracePropagation,
47
- flush: () => import_runtime_browser2.flush,
48
- initAutterBrowser: () => import_runtime_browser2.initAutterBrowser,
49
- setContext: () => import_runtime_browser2.setContext,
50
- setUser: () => import_runtime_browser2.setUser,
51
- trackEvent: () => import_runtime_browser2.trackEvent,
48
+ flush: () => import_runtime_browser3.flush,
49
+ initAutterBrowser: () => import_runtime_browser3.initAutterBrowser,
50
+ reportNextError: () => reportNextError,
51
+ setContext: () => import_runtime_browser3.setContext,
52
+ setUser: () => import_runtime_browser3.setUser,
53
+ trackEvent: () => import_runtime_browser3.trackEvent,
54
+ useAutterErrorReport: () => useAutterErrorReport,
52
55
  withFilters: () => import_filters.withFilters
53
56
  });
54
57
  module.exports = __toCommonJS(client_exports);
55
- var import_runtime_browser2 = require("@autter/runtime-browser");
58
+ var import_runtime_browser3 = require("@autter/runtime-browser");
56
59
  var import_breadcrumbs = require("@autter/runtime-browser/breadcrumbs");
57
60
  var import_tracing = require("@autter/runtime-browser/tracing");
58
61
  var import_filters = require("@autter/runtime-browser/filters");
@@ -84,9 +87,59 @@ var AutterErrorBoundary = class extends React.Component {
84
87
  return this.props.children;
85
88
  }
86
89
  };
90
+
91
+ // src/error-page.ts
92
+ var React2 = __toESM(require("react"), 1);
93
+ var import_runtime_browser2 = require("@autter/runtime-browser");
94
+
95
+ // src/control-flow.ts
96
+ function digestOf(error) {
97
+ try {
98
+ const digest = error == null ? void 0 : error.digest;
99
+ return typeof digest === "string" ? digest : "";
100
+ } catch {
101
+ return "";
102
+ }
103
+ }
104
+
105
+ // src/error-page.ts
106
+ var reported = /* @__PURE__ */ new WeakSet();
107
+ function reportNextError(error, options = {}) {
108
+ var _a;
109
+ try {
110
+ if (error && typeof error === "object") {
111
+ if (reported.has(error)) return;
112
+ reported.add(error);
113
+ }
114
+ const digest = digestOf(error);
115
+ (0, import_runtime_browser2.captureException)(error, {
116
+ ...options.context,
117
+ "next.error_boundary": (_a = options.boundary) != null ? _a : "error",
118
+ ...digest ? { "next.digest": digest.slice(0, 100) } : {}
119
+ });
120
+ } catch {
121
+ }
122
+ }
123
+ function useAutterErrorReport(error, options) {
124
+ reportNextError(error, options);
125
+ }
126
+ function AutterGlobalError({ error, reset }) {
127
+ useAutterErrorReport(error, { boundary: "global-error" });
128
+ return React2.createElement(
129
+ "html",
130
+ { lang: "en" },
131
+ React2.createElement(
132
+ "body",
133
+ null,
134
+ React2.createElement("h2", null, "Something went wrong"),
135
+ reset ? React2.createElement("button", { type: "button", onClick: () => reset() }, "Try again") : null
136
+ )
137
+ );
138
+ }
87
139
  // Annotate the CommonJS export names for ESM import in node:
88
140
  0 && (module.exports = {
89
141
  AutterErrorBoundary,
142
+ AutterGlobalError,
90
143
  addBreadcrumb,
91
144
  autterErrorFromResponse,
92
145
  captureException,
@@ -99,8 +152,10 @@ var AutterErrorBoundary = class extends React.Component {
99
152
  enableTracePropagation,
100
153
  flush,
101
154
  initAutterBrowser,
155
+ reportNextError,
102
156
  setContext,
103
157
  setUser,
104
158
  trackEvent,
159
+ useAutterErrorReport,
105
160
  withFilters
106
161
  });
package/dist/client.d.cts CHANGED
@@ -29,4 +29,48 @@ declare class AutterErrorBoundary extends React.Component<AutterErrorBoundaryPro
29
29
  render(): React.ReactNode;
30
30
  }
31
31
 
32
- export { AutterErrorBoundary, type AutterErrorBoundaryProps };
32
+ /**
33
+ * Next.js error pages report through Autter (RF-04). `app/error.tsx` and
34
+ * `app/global-error.tsx` receive the error React caught; report it while the
35
+ * page renders, before React logs it, so it is sent once, with the boundary
36
+ * and Next's `digest` (which names the server-side error onRequestError
37
+ * reported, when it came from the server):
38
+ *
39
+ * // app/error.tsx
40
+ * "use client";
41
+ * import { useAutterErrorReport } from "@autter/runtime-next/client";
42
+ * export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
43
+ * useAutterErrorReport(error);
44
+ * return <button onClick={reset}>Try again</button>;
45
+ * }
46
+ *
47
+ * // app/global-error.tsx
48
+ * "use client";
49
+ * export { AutterGlobalError as default } from "@autter/runtime-next/client";
50
+ */
51
+ interface NextErrorReportOptions {
52
+ /** Which file caught it: "error" (default) or "global-error". */
53
+ boundary?: "error" | "global-error";
54
+ /** Extra context for the event. */
55
+ context?: Record<string, unknown>;
56
+ }
57
+ /** Report an error a Next.js error page received, once per error object. */
58
+ declare function reportNextError(error: unknown, options?: NextErrorReportOptions): void;
59
+ /**
60
+ * For `app/error.tsx` (and custom `global-error.tsx` pages): reports the
61
+ * error during render (once, Strict Mode's double render included).
62
+ */
63
+ declare function useAutterErrorReport(error: unknown, options?: NextErrorReportOptions): void;
64
+ interface AutterGlobalErrorProps {
65
+ error: Error & {
66
+ digest?: string;
67
+ };
68
+ reset?: () => void;
69
+ }
70
+ /**
71
+ * A ready `app/global-error.tsx`: reports the error and renders a minimal
72
+ * page (it replaces the root layout, so it brings its own `<html>`).
73
+ */
74
+ declare function AutterGlobalError({ error, reset }: AutterGlobalErrorProps): React.ReactElement;
75
+
76
+ export { AutterErrorBoundary, type AutterErrorBoundaryProps, AutterGlobalError, type AutterGlobalErrorProps, type NextErrorReportOptions, reportNextError, useAutterErrorReport };
package/dist/client.d.ts CHANGED
@@ -29,4 +29,48 @@ declare class AutterErrorBoundary extends React.Component<AutterErrorBoundaryPro
29
29
  render(): React.ReactNode;
30
30
  }
31
31
 
32
- export { AutterErrorBoundary, type AutterErrorBoundaryProps };
32
+ /**
33
+ * Next.js error pages report through Autter (RF-04). `app/error.tsx` and
34
+ * `app/global-error.tsx` receive the error React caught; report it while the
35
+ * page renders, before React logs it, so it is sent once, with the boundary
36
+ * and Next's `digest` (which names the server-side error onRequestError
37
+ * reported, when it came from the server):
38
+ *
39
+ * // app/error.tsx
40
+ * "use client";
41
+ * import { useAutterErrorReport } from "@autter/runtime-next/client";
42
+ * export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
43
+ * useAutterErrorReport(error);
44
+ * return <button onClick={reset}>Try again</button>;
45
+ * }
46
+ *
47
+ * // app/global-error.tsx
48
+ * "use client";
49
+ * export { AutterGlobalError as default } from "@autter/runtime-next/client";
50
+ */
51
+ interface NextErrorReportOptions {
52
+ /** Which file caught it: "error" (default) or "global-error". */
53
+ boundary?: "error" | "global-error";
54
+ /** Extra context for the event. */
55
+ context?: Record<string, unknown>;
56
+ }
57
+ /** Report an error a Next.js error page received, once per error object. */
58
+ declare function reportNextError(error: unknown, options?: NextErrorReportOptions): void;
59
+ /**
60
+ * For `app/error.tsx` (and custom `global-error.tsx` pages): reports the
61
+ * error during render (once, Strict Mode's double render included).
62
+ */
63
+ declare function useAutterErrorReport(error: unknown, options?: NextErrorReportOptions): void;
64
+ interface AutterGlobalErrorProps {
65
+ error: Error & {
66
+ digest?: string;
67
+ };
68
+ reset?: () => void;
69
+ }
70
+ /**
71
+ * A ready `app/global-error.tsx`: reports the error and renders a minimal
72
+ * page (it replaces the root layout, so it brings its own `<html>`).
73
+ */
74
+ declare function AutterGlobalError({ error, reset }: AutterGlobalErrorProps): React.ReactElement;
75
+
76
+ export { AutterErrorBoundary, type AutterErrorBoundaryProps, AutterGlobalError, type AutterGlobalErrorProps, type NextErrorReportOptions, reportNextError, useAutterErrorReport };
package/dist/client.js CHANGED
@@ -6,7 +6,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6
6
  // src/client.ts
7
7
  import {
8
8
  initAutterBrowser,
9
- captureException as captureException2,
9
+ captureException as captureException3,
10
10
  captureOutcome,
11
11
  captureMessage,
12
12
  trackEvent,
@@ -56,11 +56,61 @@ var AutterErrorBoundary = class extends React.Component {
56
56
  return this.props.children;
57
57
  }
58
58
  };
59
+
60
+ // src/error-page.ts
61
+ import * as React2 from "react";
62
+ import { captureException as captureException2 } from "@autter/runtime-browser";
63
+
64
+ // src/control-flow.ts
65
+ function digestOf(error) {
66
+ try {
67
+ const digest = error == null ? void 0 : error.digest;
68
+ return typeof digest === "string" ? digest : "";
69
+ } catch {
70
+ return "";
71
+ }
72
+ }
73
+
74
+ // src/error-page.ts
75
+ var reported = /* @__PURE__ */ new WeakSet();
76
+ function reportNextError(error, options = {}) {
77
+ var _a;
78
+ try {
79
+ if (error && typeof error === "object") {
80
+ if (reported.has(error)) return;
81
+ reported.add(error);
82
+ }
83
+ const digest = digestOf(error);
84
+ captureException2(error, {
85
+ ...options.context,
86
+ "next.error_boundary": (_a = options.boundary) != null ? _a : "error",
87
+ ...digest ? { "next.digest": digest.slice(0, 100) } : {}
88
+ });
89
+ } catch {
90
+ }
91
+ }
92
+ function useAutterErrorReport(error, options) {
93
+ reportNextError(error, options);
94
+ }
95
+ function AutterGlobalError({ error, reset }) {
96
+ useAutterErrorReport(error, { boundary: "global-error" });
97
+ return React2.createElement(
98
+ "html",
99
+ { lang: "en" },
100
+ React2.createElement(
101
+ "body",
102
+ null,
103
+ React2.createElement("h2", null, "Something went wrong"),
104
+ reset ? React2.createElement("button", { type: "button", onClick: () => reset() }, "Try again") : null
105
+ )
106
+ );
107
+ }
59
108
  export {
60
109
  AutterErrorBoundary,
110
+ AutterGlobalError,
61
111
  addBreadcrumb,
62
112
  autterErrorFromResponse,
63
- captureException2 as captureException,
113
+ captureException3 as captureException,
64
114
  captureMessage,
65
115
  captureOutcome,
66
116
  clearBreadcrumbs,
@@ -70,8 +120,10 @@ export {
70
120
  enableTracePropagation,
71
121
  flush,
72
122
  initAutterBrowser,
123
+ reportNextError,
73
124
  setContext,
74
125
  setUser,
75
126
  trackEvent,
127
+ useAutterErrorReport,
76
128
  withFilters
77
129
  };
package/dist/index.cjs CHANGED
@@ -60,6 +60,7 @@ __export(src_exports, {
60
60
  runtimeLogger: () => import_runtime_node2.runtimeLogger,
61
61
  toClientError: () => import_runtime_node2.toClientError,
62
62
  trackLlmCall: () => import_runtime_node2.trackLlmCall,
63
+ withAutter: () => withAutter,
63
64
  withLlmCall: () => import_runtime_node2.withLlmCall,
64
65
  withProcessSpan: () => import_runtime_node2.withProcessSpan,
65
66
  withRuntimeOperation: () => import_runtime_node2.withRuntimeOperation,
@@ -73,7 +74,7 @@ var import_runtime_node = require("@autter/runtime-node");
73
74
  // package.json
74
75
  var package_default = {
75
76
  name: "@autter/runtime-next",
76
- version: "1.8.0",
77
+ version: "1.9.0",
77
78
  description: "One-command Autter Runtime for Next.js: server OTel, request wide events, coded errors, browser tracker, relay route, edge middleware and React error boundary",
78
79
  license: "MIT",
79
80
  type: "module",
@@ -128,9 +129,9 @@ var package_default = {
128
129
  test: "npm run build -w @autter/runtime-core && npm run build -w @autter/runtime-node && npm run build -w @autter/runtime-edge && npm run build -w @autter/runtime-browser && npm run build && node --test test/*.test.mjs"
129
130
  },
130
131
  dependencies: {
131
- "@autter/runtime-browser": "^1.7.0",
132
- "@autter/runtime-edge": "^1.2.0",
133
- "@autter/runtime-node": "^1.8.0"
132
+ "@autter/runtime-browser": "^1.8.0",
133
+ "@autter/runtime-edge": "^1.4.0",
134
+ "@autter/runtime-node": "^1.9.0"
134
135
  },
135
136
  peerDependencies: {
136
137
  react: ">=18"
@@ -159,6 +160,20 @@ var package_default = {
159
160
  ]
160
161
  };
161
162
 
163
+ // src/control-flow.ts
164
+ var CONTROL_FLOW_DIGEST = /^(?:NEXT_REDIRECT|NEXT_NOT_FOUND|NEXT_HTTP_ERROR_FALLBACK|DYNAMIC_SERVER_USAGE|BAILOUT_TO_CLIENT_SIDE_RENDERING)\b/;
165
+ function digestOf(error) {
166
+ try {
167
+ const digest = error?.digest;
168
+ return typeof digest === "string" ? digest : "";
169
+ } catch {
170
+ return "";
171
+ }
172
+ }
173
+ function isNextControlFlow(error) {
174
+ return CONTROL_FLOW_DIGEST.test(digestOf(error));
175
+ }
176
+
162
177
  // src/server.ts
163
178
  var import_runtime_node2 = require("@autter/runtime-node");
164
179
  function registerAutter(options) {
@@ -201,6 +216,24 @@ function withRuntimeRequest(handler, options = {}) {
201
216
  waitUntil: options.waitUntil ?? scheduleAfter
202
217
  });
203
218
  }
219
+ function withAutter(handler, options = {}) {
220
+ const rule = options.capture;
221
+ return withRuntimeRequest(
222
+ async (request, ...rest) => {
223
+ try {
224
+ return await handler(request, ...rest);
225
+ } catch (error) {
226
+ if (isNextControlFlow(error)) import_runtime_node.runtimeContext.outcome("succeeded");
227
+ throw error;
228
+ }
229
+ },
230
+ {
231
+ ...options,
232
+ capture: (error) => !isNextControlFlow(error) && (typeof rule === "function" ? rule(error) === true : rule !== false),
233
+ errorResponse: (error) => !isNextControlFlow(error)
234
+ }
235
+ );
236
+ }
204
237
  // Annotate the CommonJS export names for ESM import in node:
205
238
  0 && (module.exports = {
206
239
  CODE_PATTERN,
@@ -243,6 +276,7 @@ function withRuntimeRequest(handler, options = {}) {
243
276
  runtimeLogger,
244
277
  toClientError,
245
278
  trackLlmCall,
279
+ withAutter,
246
280
  withLlmCall,
247
281
  withProcessSpan,
248
282
  withRuntimeOperation,
package/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- export { createAutterRelayRoute, registerAutter, withRuntimeRequest } from './server.cjs';
2
- export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
1
+ export { AutterRouteOptions, createAutterRelayRoute, registerAutter, withAutter, withRuntimeRequest } from './server.cjs';
2
+ export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, CaptureLoggedErrorsOption, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, LoggedErrorSource, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { createAutterRelayRoute, registerAutter, withRuntimeRequest } from './server.js';
2
- export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
1
+ export { AutterRouteOptions, createAutterRelayRoute, registerAutter, withAutter, withRuntimeRequest } from './server.js';
2
+ export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, CaptureLoggedErrorsOption, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, LoggedErrorSource, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
package/dist/index.js CHANGED
@@ -39,11 +39,12 @@ import {
39
39
  runtimeLogger,
40
40
  toClientError,
41
41
  trackLlmCall,
42
+ withAutter,
42
43
  withLlmCall,
43
44
  withProcessSpan,
44
45
  withRuntimeOperation,
45
46
  withRuntimeRequest
46
- } from "./chunk-FU5HRQKM.js";
47
+ } from "./chunk-6MFPMECS.js";
47
48
  export {
48
49
  CODE_PATTERN,
49
50
  RuntimeError,
@@ -85,6 +86,7 @@ export {
85
86
  runtimeLogger,
86
87
  toClientError,
87
88
  trackLlmCall,
89
+ withAutter,
88
90
  withLlmCall,
89
91
  withProcessSpan,
90
92
  withRuntimeOperation,
@@ -27,6 +27,8 @@ module.exports = __toCommonJS(instrumentation_edge_exports);
27
27
 
28
28
  // src/request-error.ts
29
29
  var import_runtime_edge = require("@autter/runtime-edge");
30
+
31
+ // src/control-flow.ts
30
32
  var CONTROL_FLOW_DIGEST = /^(?:NEXT_REDIRECT|NEXT_NOT_FOUND|NEXT_HTTP_ERROR_FALLBACK|DYNAMIC_SERVER_USAGE|BAILOUT_TO_CLIENT_SIDE_RENDERING)\b/;
31
33
  function digestOf(error) {
32
34
  try {
@@ -36,6 +38,11 @@ function digestOf(error) {
36
38
  return "";
37
39
  }
38
40
  }
41
+ function isNextControlFlow(error) {
42
+ return CONTROL_FLOW_DIGEST.test(digestOf(error));
43
+ }
44
+
45
+ // src/request-error.ts
39
46
  function shouldReport(error, rule) {
40
47
  if (rule === true) return true;
41
48
  if (rule === false) return false;
@@ -46,7 +53,7 @@ function shouldReport(error, rule) {
46
53
  return false;
47
54
  }
48
55
  }
49
- return !CONTROL_FLOW_DIGEST.test(digestOf(error));
56
+ return !isNextControlFlow(error);
50
57
  }
51
58
  function requestErrorAttributes(error, request, context) {
52
59
  const out = {};
@@ -2,7 +2,7 @@ import {
2
2
  reportOnEdge,
3
3
  requestErrorAttributes,
4
4
  shouldReport
5
- } from "./chunk-CL2ENM4A.js";
5
+ } from "./chunk-Q2TA3ACY.js";
6
6
 
7
7
  // src/instrumentation-edge.ts
8
8
  function autterOnRequestError(options = {}) {
@@ -37,6 +37,8 @@ module.exports = __toCommonJS(instrumentation_exports);
37
37
 
38
38
  // src/request-error.ts
39
39
  var import_runtime_edge = require("@autter/runtime-edge");
40
+
41
+ // src/control-flow.ts
40
42
  var CONTROL_FLOW_DIGEST = /^(?:NEXT_REDIRECT|NEXT_NOT_FOUND|NEXT_HTTP_ERROR_FALLBACK|DYNAMIC_SERVER_USAGE|BAILOUT_TO_CLIENT_SIDE_RENDERING)\b/;
41
43
  function digestOf(error) {
42
44
  try {
@@ -46,6 +48,11 @@ function digestOf(error) {
46
48
  return "";
47
49
  }
48
50
  }
51
+ function isNextControlFlow(error) {
52
+ return CONTROL_FLOW_DIGEST.test(digestOf(error));
53
+ }
54
+
55
+ // src/request-error.ts
49
56
  function shouldReport(error, rule) {
50
57
  if (rule === true) return true;
51
58
  if (rule === false) return false;
@@ -56,7 +63,7 @@ function shouldReport(error, rule) {
56
63
  return false;
57
64
  }
58
65
  }
59
- return !CONTROL_FLOW_DIGEST.test(digestOf(error));
66
+ return !isNextControlFlow(error);
60
67
  }
61
68
  function requestErrorAttributes(error, request, context) {
62
69
  const out = {};
@@ -2,7 +2,7 @@ import {
2
2
  reportOnEdge,
3
3
  requestErrorAttributes,
4
4
  shouldReport
5
- } from "./chunk-CL2ENM4A.js";
5
+ } from "./chunk-Q2TA3ACY.js";
6
6
 
7
7
  // src/instrumentation.ts
8
8
  function autterOnRequestError(options = {}) {
package/dist/server.cjs CHANGED
@@ -60,6 +60,7 @@ __export(server_exports, {
60
60
  runtimeLogger: () => import_runtime_node2.runtimeLogger,
61
61
  toClientError: () => import_runtime_node2.toClientError,
62
62
  trackLlmCall: () => import_runtime_node2.trackLlmCall,
63
+ withAutter: () => withAutter,
63
64
  withLlmCall: () => import_runtime_node2.withLlmCall,
64
65
  withProcessSpan: () => import_runtime_node2.withProcessSpan,
65
66
  withRuntimeOperation: () => import_runtime_node2.withRuntimeOperation,
@@ -71,7 +72,7 @@ var import_runtime_node = require("@autter/runtime-node");
71
72
  // package.json
72
73
  var package_default = {
73
74
  name: "@autter/runtime-next",
74
- version: "1.8.0",
75
+ version: "1.9.0",
75
76
  description: "One-command Autter Runtime for Next.js: server OTel, request wide events, coded errors, browser tracker, relay route, edge middleware and React error boundary",
76
77
  license: "MIT",
77
78
  type: "module",
@@ -126,9 +127,9 @@ var package_default = {
126
127
  test: "npm run build -w @autter/runtime-core && npm run build -w @autter/runtime-node && npm run build -w @autter/runtime-edge && npm run build -w @autter/runtime-browser && npm run build && node --test test/*.test.mjs"
127
128
  },
128
129
  dependencies: {
129
- "@autter/runtime-browser": "^1.7.0",
130
- "@autter/runtime-edge": "^1.2.0",
131
- "@autter/runtime-node": "^1.8.0"
130
+ "@autter/runtime-browser": "^1.8.0",
131
+ "@autter/runtime-edge": "^1.4.0",
132
+ "@autter/runtime-node": "^1.9.0"
132
133
  },
133
134
  peerDependencies: {
134
135
  react: ">=18"
@@ -157,6 +158,20 @@ var package_default = {
157
158
  ]
158
159
  };
159
160
 
161
+ // src/control-flow.ts
162
+ var CONTROL_FLOW_DIGEST = /^(?:NEXT_REDIRECT|NEXT_NOT_FOUND|NEXT_HTTP_ERROR_FALLBACK|DYNAMIC_SERVER_USAGE|BAILOUT_TO_CLIENT_SIDE_RENDERING)\b/;
163
+ function digestOf(error) {
164
+ try {
165
+ const digest = error?.digest;
166
+ return typeof digest === "string" ? digest : "";
167
+ } catch {
168
+ return "";
169
+ }
170
+ }
171
+ function isNextControlFlow(error) {
172
+ return CONTROL_FLOW_DIGEST.test(digestOf(error));
173
+ }
174
+
160
175
  // src/server.ts
161
176
  var import_runtime_node2 = require("@autter/runtime-node");
162
177
  function registerAutter(options) {
@@ -199,6 +214,24 @@ function withRuntimeRequest(handler, options = {}) {
199
214
  waitUntil: options.waitUntil ?? scheduleAfter
200
215
  });
201
216
  }
217
+ function withAutter(handler, options = {}) {
218
+ const rule = options.capture;
219
+ return withRuntimeRequest(
220
+ async (request, ...rest) => {
221
+ try {
222
+ return await handler(request, ...rest);
223
+ } catch (error) {
224
+ if (isNextControlFlow(error)) import_runtime_node.runtimeContext.outcome("succeeded");
225
+ throw error;
226
+ }
227
+ },
228
+ {
229
+ ...options,
230
+ capture: (error) => !isNextControlFlow(error) && (typeof rule === "function" ? rule(error) === true : rule !== false),
231
+ errorResponse: (error) => !isNextControlFlow(error)
232
+ }
233
+ );
234
+ }
202
235
  // Annotate the CommonJS export names for ESM import in node:
203
236
  0 && (module.exports = {
204
237
  CODE_PATTERN,
@@ -241,6 +274,7 @@ function withRuntimeRequest(handler, options = {}) {
241
274
  runtimeLogger,
242
275
  toClientError,
243
276
  trackLlmCall,
277
+ withAutter,
244
278
  withLlmCall,
245
279
  withProcessSpan,
246
280
  withRuntimeOperation,
package/dist/server.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { RelayOptions, AutterServerOptions, AutterServer, RuntimeRequestOptions } from '@autter/runtime-node';
2
- export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
1
+ import { RuntimeRequestOptions, RelayOptions, AutterServerOptions, AutterServer } from '@autter/runtime-node';
2
+ export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, CaptureLoggedErrorsOption, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, LoggedErrorSource, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
3
3
 
4
4
  /**
5
5
  * Server half of @autter/runtime-next. Safe to import anywhere Node runs:
@@ -35,6 +35,15 @@ export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErr
35
35
  *
36
36
  * The log flush is handed to Next's `after()` automatically.
37
37
  *
38
+ * 4. Route handlers that answer thrown errors (RF-04):
39
+ *
40
+ * import { withAutter, RuntimeError } from "@autter/runtime-next";
41
+ * export const GET = withAutter(async (request) => {
42
+ * throw new RuntimeError({ status: 404, code: "orders.not_found", message: "No such order" });
43
+ * });
44
+ *
45
+ * The thrown 404 is recorded with its stack and answered as a 404.
46
+ *
38
47
  * Browser tracker + error boundary live in `@autter/runtime-next/client`;
39
48
  * `middleware.ts` (edge runtime) uses `@autter/runtime-next/edge`.
40
49
  */
@@ -51,5 +60,29 @@ declare function createAutterRelayRoute(options: RelayOptions): {
51
60
  * `unstable_after` on 14.2) unless you pass your own `waitUntil`.
52
61
  */
53
62
  declare function withRuntimeRequest<A extends unknown[]>(handler: (request: Request, ...rest: A) => Response | Promise<Response>, options?: RuntimeRequestOptions): (request: Request, ...rest: A) => Promise<Response>;
63
+ interface AutterRouteOptions extends Omit<RuntimeRequestOptions, "capture" | "errorResponse"> {
64
+ /**
65
+ * Which thrown errors are reported. Default: every one except Next's
66
+ * control-flow signals (`redirect()`, `notFound()`, …), which always
67
+ * pass through to Next untouched.
68
+ */
69
+ capture?: boolean | ((error: unknown) => boolean);
70
+ }
71
+ /**
72
+ * Route handler wrapper (RF-04): a request summary like `withRuntimeRequest`,
73
+ * and a thrown error is recorded with its stack on the request span, then
74
+ * answered with `toClientError` JSON and the error's own status, so a thrown
75
+ * 4xx (a `RuntimeError` with `status: 404`, any error with a 4xx `status`)
76
+ * stays a 4xx and keeps its stack instead of becoming an anonymous 500.
77
+ * Next's `redirect()` / `notFound()` signals are rethrown for Next to
78
+ * answer, and never reported.
79
+ *
80
+ * export const POST = withAutter(async (request) => {
81
+ * const order = await findOrder(request);
82
+ * if (!order) throw new RuntimeError({ status: 404, code: "orders.not_found", message: "No such order" });
83
+ * return Response.json(order);
84
+ * });
85
+ */
86
+ declare function withAutter<A extends unknown[]>(handler: (request: Request, ...rest: A) => Response | Promise<Response>, options?: AutterRouteOptions): (request: Request, ...rest: A) => Promise<Response>;
54
87
 
55
- export { createAutterRelayRoute, registerAutter, withRuntimeRequest };
88
+ export { type AutterRouteOptions, createAutterRelayRoute, registerAutter, withAutter, withRuntimeRequest };
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { RelayOptions, AutterServerOptions, AutterServer, RuntimeRequestOptions } from '@autter/runtime-node';
2
- export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
1
+ import { RuntimeRequestOptions, RelayOptions, AutterServerOptions, AutterServer } from '@autter/runtime-node';
2
+ export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErrorResponseOptions, AutterLogging, AutterLoggingOptions, AutterRequestsOptions, AutterServer, AutterServerOptions, Breadcrumb, BreadcrumbInput, CODE_PATTERN, CaptureLoggedErrorsOption, ClientErrorBody, ConsoleSinkOptions, FileSinkOptions, FlushTarget, InstrumentLlmOptions, LlmCallHandle, LlmCallInfo, LlmUsage, LoggedErrorSource, OtlpSinkOptions, RedactOptions, RelayOptions, RuntimeCarrier, RuntimeContextHandle, RuntimeEnrichContext, RuntimeEnrichEvent, RuntimeEnricher, RuntimeError, RuntimeErrorCatalog, RuntimeErrorDefinition, RuntimeErrorExtras, RuntimeErrorFactory, RuntimeErrorLike, RuntimeErrorOptions, RuntimeEvent, RuntimeLogContext, RuntimeLogContextValue, RuntimeLogLevel, RuntimeLoggingOptions, RuntimeOperation, RuntimeOperationKind, RuntimeOperationOptions, RuntimeOutcome, RuntimeRequestOptions, RuntimeSink, RuntimeSinkContext, SafeCapture, TrackedLlmCall, addBreadcrumb, autterErrorHandler, autterErrorResponse, autterFastify, autterFastifyErrors, autterKoa, autterRequests, captureRequestError, captureException as captureServerException, captureMessage as captureServerMessage, consoleSink, createRuntimeLogger, defineRuntimeErrors, emitLlmSelftestTrace, enrichDeployment, enrichEdgeGeo, enrichRequestSize, enrichUserAgent, errorAttributes, fileSink, flushRuntimeLogs, initAutterLogging, installAutterAutoFlush, instrumentLlmClient, isRuntimeErrorLike, makeSafeCapture, otlpSink, redactAttributes, redactText, reportOutcome as reportServerOutcome, runInBackground, runtimeContext, runtimeLogStats, runtimeLogger, toClientError, trackLlmCall, withLlmCall, withProcessSpan, withRuntimeOperation } from '@autter/runtime-node';
3
3
 
4
4
  /**
5
5
  * Server half of @autter/runtime-next. Safe to import anywhere Node runs:
@@ -35,6 +35,15 @@ export { AutoFlushHandle, AutoFlushOptions, AutterErrorHandlerOptions, AutterErr
35
35
  *
36
36
  * The log flush is handed to Next's `after()` automatically.
37
37
  *
38
+ * 4. Route handlers that answer thrown errors (RF-04):
39
+ *
40
+ * import { withAutter, RuntimeError } from "@autter/runtime-next";
41
+ * export const GET = withAutter(async (request) => {
42
+ * throw new RuntimeError({ status: 404, code: "orders.not_found", message: "No such order" });
43
+ * });
44
+ *
45
+ * The thrown 404 is recorded with its stack and answered as a 404.
46
+ *
38
47
  * Browser tracker + error boundary live in `@autter/runtime-next/client`;
39
48
  * `middleware.ts` (edge runtime) uses `@autter/runtime-next/edge`.
40
49
  */
@@ -51,5 +60,29 @@ declare function createAutterRelayRoute(options: RelayOptions): {
51
60
  * `unstable_after` on 14.2) unless you pass your own `waitUntil`.
52
61
  */
53
62
  declare function withRuntimeRequest<A extends unknown[]>(handler: (request: Request, ...rest: A) => Response | Promise<Response>, options?: RuntimeRequestOptions): (request: Request, ...rest: A) => Promise<Response>;
63
+ interface AutterRouteOptions extends Omit<RuntimeRequestOptions, "capture" | "errorResponse"> {
64
+ /**
65
+ * Which thrown errors are reported. Default: every one except Next's
66
+ * control-flow signals (`redirect()`, `notFound()`, …), which always
67
+ * pass through to Next untouched.
68
+ */
69
+ capture?: boolean | ((error: unknown) => boolean);
70
+ }
71
+ /**
72
+ * Route handler wrapper (RF-04): a request summary like `withRuntimeRequest`,
73
+ * and a thrown error is recorded with its stack on the request span, then
74
+ * answered with `toClientError` JSON and the error's own status, so a thrown
75
+ * 4xx (a `RuntimeError` with `status: 404`, any error with a 4xx `status`)
76
+ * stays a 4xx and keeps its stack instead of becoming an anonymous 500.
77
+ * Next's `redirect()` / `notFound()` signals are rethrown for Next to
78
+ * answer, and never reported.
79
+ *
80
+ * export const POST = withAutter(async (request) => {
81
+ * const order = await findOrder(request);
82
+ * if (!order) throw new RuntimeError({ status: 404, code: "orders.not_found", message: "No such order" });
83
+ * return Response.json(order);
84
+ * });
85
+ */
86
+ declare function withAutter<A extends unknown[]>(handler: (request: Request, ...rest: A) => Response | Promise<Response>, options?: AutterRouteOptions): (request: Request, ...rest: A) => Promise<Response>;
54
87
 
55
- export { createAutterRelayRoute, registerAutter, withRuntimeRequest };
88
+ export { type AutterRouteOptions, createAutterRelayRoute, registerAutter, withAutter, withRuntimeRequest };
package/dist/server.js CHANGED
@@ -39,11 +39,12 @@ import {
39
39
  runtimeLogger,
40
40
  toClientError,
41
41
  trackLlmCall,
42
+ withAutter,
42
43
  withLlmCall,
43
44
  withProcessSpan,
44
45
  withRuntimeOperation,
45
46
  withRuntimeRequest
46
- } from "./chunk-FU5HRQKM.js";
47
+ } from "./chunk-6MFPMECS.js";
47
48
  export {
48
49
  CODE_PATTERN,
49
50
  RuntimeError,
@@ -85,6 +86,7 @@ export {
85
86
  runtimeLogger,
86
87
  toClientError,
87
88
  trackLlmCall,
89
+ withAutter,
88
90
  withLlmCall,
89
91
  withProcessSpan,
90
92
  withRuntimeOperation,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autter/runtime-next",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "One-command Autter Runtime for Next.js: server OTel, request wide events, coded errors, browser tracker, relay route, edge middleware and React error boundary",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -55,9 +55,9 @@
55
55
  "test": "npm run build -w @autter/runtime-core && npm run build -w @autter/runtime-node && npm run build -w @autter/runtime-edge && npm run build -w @autter/runtime-browser && npm run build && node --test test/*.test.mjs"
56
56
  },
57
57
  "dependencies": {
58
- "@autter/runtime-browser": "^1.7.0",
59
- "@autter/runtime-edge": "^1.2.0",
60
- "@autter/runtime-node": "^1.8.0"
58
+ "@autter/runtime-browser": "^1.8.0",
59
+ "@autter/runtime-edge": "^1.4.0",
60
+ "@autter/runtime-node": "^1.9.0"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "react": ">=18"