@trpc/next 11.0.0-next.323 → 11.0.0-next.324

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.
@@ -1,4 +1,4 @@
1
- import type { AnyProcedure, AnyRootTypes, AnyRouter, inferClientTypes, MaybePromise, RootConfig, Simplify, TRPCResponse } from '@trpc/server/unstable-core-do-not-import';
1
+ import type { AnyProcedure, AnyRootTypes, AnyRouter, ErrorHandlerOptions, inferClientTypes, MaybePromise, RootConfig, Simplify, TRPCResponse } from '@trpc/server/unstable-core-do-not-import';
2
2
  import type { ActionHandlerDef, CreateTRPCNextAppRouterOptions, inferActionDef } from './shared';
3
3
  import type { NextAppDirDecorateRouterRecord } from './types';
4
4
  export declare function experimental_createTRPCNextAppDirServer<TRouter extends AnyRouter>(opts: CreateTRPCNextAppRouterOptions<TRouter>): NextAppDirDecorateRouterRecord<TRouter["_def"]["_config"]["$types"], TRouter["_def"]["record"]>;
@@ -8,13 +8,25 @@ export declare function experimental_createTRPCNextAppDirServer<TRouter extends
8
8
  export type TRPCActionHandler<TDef extends ActionHandlerDef> = (input: FormData | TDef['input']) => Promise<TRPCResponse<TDef['output'], TDef['errorShape']>>;
9
9
  export declare function experimental_createServerActionHandler<TInstance extends {
10
10
  _config: RootConfig<AnyRootTypes>;
11
- }>(t: TInstance, opts: {
11
+ }>(t: TInstance, opts: (object extends TInstance['_config']['$types']['ctx'] ? {
12
+ createContext?: () => MaybePromise<TInstance['_config']['$types']['ctx']>;
13
+ } : {
12
14
  createContext: () => MaybePromise<TInstance['_config']['$types']['ctx']>;
15
+ }) & {
13
16
  /**
14
17
  * Transform form data to a `Record` before passing it to the procedure
15
18
  * @default true
16
19
  */
17
20
  normalizeFormData?: boolean;
21
+ /**
22
+ * Called when an error occurs in the handler
23
+ */
24
+ onError?: (opts: ErrorHandlerOptions<TInstance['_config']['$types']['ctx']>) => void;
25
+ /**
26
+ * Rethrow errors that should be handled by Next.js
27
+ * @default true
28
+ */
29
+ rethrowNextErrors?: boolean;
18
30
  }): <TProc extends AnyProcedure>(proc: TProc) => TRPCActionHandler<Simplify<inferActionDef<inferClientTypes<TInstance>, TProc>>>;
19
31
  export declare function experimental_revalidateEndpoint(req: Request): Promise<Response>;
20
32
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/app-dir/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAEhB,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,YAAY,EACb,MAAM,0CAA0C,CAAC;AAWlD,OAAO,KAAK,EACV,gBAAgB,EAChB,8BAA8B,EAC9B,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AAG9D,wBAAgB,uCAAuC,CACrD,OAAO,SAAS,SAAS,EACzB,IAAI,EAAE,8BAA8B,CAAC,OAAO,CAAC,mGA2B9C;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,gBAAgB,IAAI,CAC7D,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAC5B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAE/D,wBAAgB,sCAAsC,CACpD,SAAS,SAAS;IAChB,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;CACnC,EAED,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE;IACJ,aAAa,EAAE,MAAM,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACzE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,sCASO,KAAK,KACV,kBACD,SAAS,eAAe,iBAAiB,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC,CAC7D,CAwDF;AAGD,wBAAsB,+BAA+B,CAAC,GAAG,EAAE,OAAO,qBAiBjE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/app-dir/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAEhB,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,YAAY,EACb,MAAM,0CAA0C,CAAC;AAalD,OAAO,KAAK,EACV,gBAAgB,EAChB,8BAA8B,EAC9B,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AAG9D,wBAAgB,uCAAuC,CACrD,OAAO,SAAS,SAAS,EACzB,IAAI,EAAE,8BAA8B,CAAC,OAAO,CAAC,mGA2B9C;AAWD;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,gBAAgB,IAAI,CAC7D,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAC5B,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAE/D,wBAAgB,sCAAsC,CACpD,SAAS,SAAS;IAChB,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;CACnC,EAED,CAAC,EAAE,SAAS,EACZ,IAAI,EAAE,CAAC,MAAM,SAAS,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GACvD;IACE,aAAa,CAAC,EAAE,MAAM,YAAY,CAChC,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CACtC,CAAC;CACH,GACD;IACE,aAAa,EAAE,MAAM,YAAY,CAC/B,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CACtC,CAAC;CACH,CAAC,GAAG;IACP;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,CACR,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAC7D,IAAI,CAAC;IAEV;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,sCAaO,KAAK,KACV,kBACD,SAAS,eAAe,iBAAiB,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC,CAC7D,CAmEF;AAGD,wBAAsB,+BAA+B,CAAC,GAAG,EAAE,OAAO,qBAiBjE"}
@@ -3,6 +3,8 @@
3
3
  var client = require('@trpc/client');
4
4
  var unstableCoreDoNotImport = require('@trpc/server/unstable-core-do-not-import');
5
5
  var cache = require('next/cache');
6
+ var notFound = require('next/dist/client/components/not-found');
7
+ var redirect = require('next/dist/client/components/redirect');
6
8
  var React = require('react');
7
9
  var formDataToObject = require('./formDataToObject.js');
8
10
  var shared = require('./shared.js');
@@ -32,18 +34,26 @@ function experimental_createTRPCNextAppDirServer(opts) {
32
34
  return client$1[procedureType](procedurePath, ...callOpts.args);
33
35
  });
34
36
  }
37
+ /**
38
+ * Rethrow errors that should be handled by Next.js
39
+ */ const throwNextErrors = (error)=>{
40
+ const { cause } = error;
41
+ if (redirect.isRedirectError(cause) || notFound.isNotFoundError(cause)) {
42
+ throw error.cause;
43
+ }
44
+ };
35
45
  function experimental_createServerActionHandler(t, opts) {
36
46
  const config = t._config;
37
- const { normalizeFormData =true , createContext } = opts;
47
+ const { normalizeFormData =true , createContext , rethrowNextErrors =true , } = opts;
38
48
  const transformer = config.transformer;
39
49
  // TODO allow this to take a `TRouter` in addition to a `AnyProcedure`
40
50
  return function createServerAction(proc) {
41
51
  return async function actionHandler(rawInput) {
42
- const ctx = undefined;
52
+ let ctx = undefined;
43
53
  try {
44
- const ctx1 = await createContext();
54
+ ctx = await createContext?.() ?? {};
45
55
  if (normalizeFormData && shared.isFormData(rawInput)) {
46
- // Normalizes formdata so we can use `z.object({})` etc on the server
56
+ // Normalizes FormData so we can use `z.object({})` etc on the server
47
57
  try {
48
58
  rawInput = formDataToObject.formDataToObject(rawInput);
49
59
  } catch {
@@ -55,10 +65,10 @@ function experimental_createServerActionHandler(t, opts) {
55
65
  } else if (rawInput && !shared.isFormData(rawInput)) {
56
66
  rawInput = transformer.input.deserialize(rawInput);
57
67
  }
58
- const data = await proc({
68
+ const data = proc._def.experimental_caller ? await proc(rawInput) : await proc({
59
69
  input: undefined,
60
- ctx: ctx1,
61
- path: 'serverAction',
70
+ ctx,
71
+ path: '',
62
72
  getRawInput: async ()=>rawInput,
63
73
  type: proc._def.type
64
74
  });
@@ -70,15 +80,22 @@ function experimental_createServerActionHandler(t, opts) {
70
80
  return transformedJSON;
71
81
  } catch (cause) {
72
82
  const error = unstableCoreDoNotImport.getTRPCErrorFromUnknown(cause);
83
+ opts.onError?.({
84
+ ctx,
85
+ error,
86
+ input: rawInput,
87
+ path: '',
88
+ type: proc._def.type
89
+ });
90
+ rethrowNextErrors && throwNextErrors(error);
73
91
  const shape = unstableCoreDoNotImport.getErrorShape({
74
92
  config,
75
93
  ctx,
76
94
  error,
77
95
  input: rawInput,
78
- path: 'serverAction',
96
+ path: '',
79
97
  type: proc._def.type
80
98
  });
81
- // TODO: send the right HTTP header?!
82
99
  return unstableCoreDoNotImport.transformTRPCResponse(t._config, {
83
100
  error: shape
84
101
  });
@@ -1,6 +1,8 @@
1
1
  import { createTRPCUntypedClient, clientCallTypeToProcedureType } from '@trpc/client';
2
2
  import { createRecursiveProxy, TRPCError, transformTRPCResponse, getTRPCErrorFromUnknown, getErrorShape } from '@trpc/server/unstable-core-do-not-import';
3
3
  import { revalidateTag } from 'next/cache';
4
+ import { isNotFoundError } from 'next/dist/client/components/not-found';
5
+ import { isRedirectError } from 'next/dist/client/components/redirect';
4
6
  import { cache } from 'react';
5
7
  import { formDataToObject } from './formDataToObject.mjs';
6
8
  import { generateCacheTag, isFormData } from './shared.mjs';
@@ -30,18 +32,26 @@ function experimental_createTRPCNextAppDirServer(opts) {
30
32
  return client[procedureType](procedurePath, ...callOpts.args);
31
33
  });
32
34
  }
35
+ /**
36
+ * Rethrow errors that should be handled by Next.js
37
+ */ const throwNextErrors = (error)=>{
38
+ const { cause } = error;
39
+ if (isRedirectError(cause) || isNotFoundError(cause)) {
40
+ throw error.cause;
41
+ }
42
+ };
33
43
  function experimental_createServerActionHandler(t, opts) {
34
44
  const config = t._config;
35
- const { normalizeFormData =true , createContext } = opts;
45
+ const { normalizeFormData =true , createContext , rethrowNextErrors =true , } = opts;
36
46
  const transformer = config.transformer;
37
47
  // TODO allow this to take a `TRouter` in addition to a `AnyProcedure`
38
48
  return function createServerAction(proc) {
39
49
  return async function actionHandler(rawInput) {
40
- const ctx = undefined;
50
+ let ctx = undefined;
41
51
  try {
42
- const ctx1 = await createContext();
52
+ ctx = await createContext?.() ?? {};
43
53
  if (normalizeFormData && isFormData(rawInput)) {
44
- // Normalizes formdata so we can use `z.object({})` etc on the server
54
+ // Normalizes FormData so we can use `z.object({})` etc on the server
45
55
  try {
46
56
  rawInput = formDataToObject(rawInput);
47
57
  } catch {
@@ -53,10 +63,10 @@ function experimental_createServerActionHandler(t, opts) {
53
63
  } else if (rawInput && !isFormData(rawInput)) {
54
64
  rawInput = transformer.input.deserialize(rawInput);
55
65
  }
56
- const data = await proc({
66
+ const data = proc._def.experimental_caller ? await proc(rawInput) : await proc({
57
67
  input: undefined,
58
- ctx: ctx1,
59
- path: 'serverAction',
68
+ ctx,
69
+ path: '',
60
70
  getRawInput: async ()=>rawInput,
61
71
  type: proc._def.type
62
72
  });
@@ -68,15 +78,22 @@ function experimental_createServerActionHandler(t, opts) {
68
78
  return transformedJSON;
69
79
  } catch (cause) {
70
80
  const error = getTRPCErrorFromUnknown(cause);
81
+ opts.onError?.({
82
+ ctx,
83
+ error,
84
+ input: rawInput,
85
+ path: '',
86
+ type: proc._def.type
87
+ });
88
+ rethrowNextErrors && throwNextErrors(error);
71
89
  const shape = getErrorShape({
72
90
  config,
73
91
  ctx,
74
92
  error,
75
93
  input: rawInput,
76
- path: 'serverAction',
94
+ path: '',
77
95
  type: proc._def.type
78
96
  });
79
- // TODO: send the right HTTP header?!
80
97
  return transformTRPCResponse(t._config, {
81
98
  error: shape
82
99
  });
@@ -1,7 +1,7 @@
1
1
  {
2
- "bundleSize": 23036,
3
- "bundleOrigSize": 37220,
4
- "bundleReduction": 38.11,
2
+ "bundleSize": 23547,
3
+ "bundleOrigSize": 38398,
4
+ "bundleReduction": 38.68,
5
5
  "modules": [
6
6
  {
7
7
  "id": "/src/ssrPrepass.ts",
@@ -12,13 +12,13 @@
12
12
  ],
13
13
  "removedExports": [],
14
14
  "dependents": [],
15
- "percent": 21.97,
15
+ "percent": 21.5,
16
16
  "reduction": 13.51
17
17
  },
18
18
  {
19
19
  "id": "/src/app-dir/server.ts",
20
- "size": 3822,
21
- "origSize": 4925,
20
+ "size": 4333,
21
+ "origSize": 6103,
22
22
  "renderedExports": [
23
23
  "experimental_createTRPCNextAppDirServer",
24
24
  "experimental_createServerActionHandler",
@@ -26,8 +26,8 @@
26
26
  ],
27
27
  "removedExports": [],
28
28
  "dependents": [],
29
- "percent": 16.59,
30
- "reduction": 22.4
29
+ "percent": 18.4,
30
+ "reduction": 29
31
31
  },
32
32
  {
33
33
  "id": "/src/withTRPC.tsx",
@@ -41,7 +41,7 @@
41
41
  "/src/index.ts",
42
42
  "/src/createTRPCNext.tsx"
43
43
  ],
44
- "percent": 14.97,
44
+ "percent": 14.64,
45
45
  "reduction": 43.83
46
46
  },
47
47
  {
@@ -56,7 +56,7 @@
56
56
  "dependents": [
57
57
  "/src/app-dir/client.ts"
58
58
  ],
59
- "percent": 14.92,
59
+ "percent": 14.59,
60
60
  "reduction": 49.31
61
61
  },
62
62
  {
@@ -68,7 +68,7 @@
68
68
  ],
69
69
  "removedExports": [],
70
70
  "dependents": [],
71
- "percent": 11.16,
71
+ "percent": 10.92,
72
72
  "reduction": 15.54
73
73
  },
74
74
  {
@@ -80,7 +80,7 @@
80
80
  ],
81
81
  "removedExports": [],
82
82
  "dependents": [],
83
- "percent": 5.55,
83
+ "percent": 5.43,
84
84
  "reduction": 32.47
85
85
  },
86
86
  {
@@ -92,7 +92,7 @@
92
92
  ],
93
93
  "removedExports": [],
94
94
  "dependents": [],
95
- "percent": 5.17,
95
+ "percent": 5.06,
96
96
  "reduction": 39.58
97
97
  },
98
98
  {
@@ -106,7 +106,7 @@
106
106
  "dependents": [
107
107
  "/src/index.ts"
108
108
  ],
109
- "percent": 4.66,
109
+ "percent": 4.56,
110
110
  "reduction": 59.52
111
111
  },
112
112
  {
@@ -120,7 +120,7 @@
120
120
  "dependents": [
121
121
  "/src/app-dir/server.ts"
122
122
  ],
123
- "percent": 3.55,
123
+ "percent": 3.47,
124
124
  "reduction": 0.97
125
125
  },
126
126
  {
@@ -140,7 +140,7 @@
140
140
  "/src/app-dir/links/nextHttp.ts",
141
141
  "/src/app-dir/create-action-hook.tsx"
142
142
  ],
143
- "percent": 1.45,
143
+ "percent": 1.42,
144
144
  "reduction": 89.11
145
145
  },
146
146
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/next",
3
- "version": "11.0.0-next.323+681d94abe",
3
+ "version": "11.0.0-next.324+d8186919f",
4
4
  "description": "The tRPC Next.js library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -73,9 +73,9 @@
73
73
  ],
74
74
  "peerDependencies": {
75
75
  "@tanstack/react-query": "^5.25.0",
76
- "@trpc/client": "11.0.0-next.323+681d94abe",
77
- "@trpc/react-query": "11.0.0-next.323+681d94abe",
78
- "@trpc/server": "11.0.0-next.323+681d94abe",
76
+ "@trpc/client": "11.0.0-next.324+d8186919f",
77
+ "@trpc/react-query": "11.0.0-next.324+d8186919f",
78
+ "@trpc/server": "11.0.0-next.324+d8186919f",
79
79
  "next": "*",
80
80
  "react": ">=16.8.0",
81
81
  "react-dom": ">=16.8.0"
@@ -90,9 +90,9 @@
90
90
  },
91
91
  "devDependencies": {
92
92
  "@tanstack/react-query": "^5.25.0",
93
- "@trpc/client": "11.0.0-next.323+681d94abe",
94
- "@trpc/react-query": "11.0.0-next.323+681d94abe",
95
- "@trpc/server": "11.0.0-next.323+681d94abe",
93
+ "@trpc/client": "11.0.0-next.324+d8186919f",
94
+ "@trpc/react-query": "11.0.0-next.324+d8186919f",
95
+ "@trpc/server": "11.0.0-next.324+d8186919f",
96
96
  "@types/express": "^4.17.17",
97
97
  "@types/node": "^20.10.0",
98
98
  "@types/react": "^18.2.33",
@@ -112,5 +112,5 @@
112
112
  "funding": [
113
113
  "https://trpc.io/sponsor"
114
114
  ],
115
- "gitHead": "681d94abee8d7dcc90c77cb44c6ca54897be2079"
115
+ "gitHead": "d8186919fd8e914d272dba92dd8310d3dfc1c095"
116
116
  }
@@ -7,6 +7,7 @@ import type {
7
7
  AnyProcedure,
8
8
  AnyRootTypes,
9
9
  AnyRouter,
10
+ ErrorHandlerOptions,
10
11
  inferClientTypes,
11
12
  inferProcedureInput,
12
13
  MaybePromise,
@@ -22,6 +23,8 @@ import {
22
23
  TRPCError,
23
24
  } from '@trpc/server/unstable-core-do-not-import';
24
25
  import { revalidateTag } from 'next/cache';
26
+ import { isNotFoundError } from 'next/dist/client/components/not-found';
27
+ import { isRedirectError } from 'next/dist/client/components/redirect';
25
28
  import { cache } from 'react';
26
29
  import { formDataToObject } from './formDataToObject';
27
30
  import type {
@@ -64,6 +67,15 @@ export function experimental_createTRPCNextAppDirServer<
64
67
  >;
65
68
  }
66
69
 
70
+ /**
71
+ * Rethrow errors that should be handled by Next.js
72
+ */
73
+ const throwNextErrors = (error: TRPCError) => {
74
+ const { cause } = error;
75
+ if (isRedirectError(cause) || isNotFoundError(cause)) {
76
+ throw error.cause;
77
+ }
78
+ };
67
79
  /**
68
80
  * @internal
69
81
  */
@@ -77,17 +89,42 @@ export function experimental_createServerActionHandler<
77
89
  },
78
90
  >(
79
91
  t: TInstance,
80
- opts: {
81
- createContext: () => MaybePromise<TInstance['_config']['$types']['ctx']>;
92
+ opts: (object extends TInstance['_config']['$types']['ctx']
93
+ ? {
94
+ createContext?: () => MaybePromise<
95
+ TInstance['_config']['$types']['ctx']
96
+ >;
97
+ }
98
+ : {
99
+ createContext: () => MaybePromise<
100
+ TInstance['_config']['$types']['ctx']
101
+ >;
102
+ }) & {
82
103
  /**
83
104
  * Transform form data to a `Record` before passing it to the procedure
84
105
  * @default true
85
106
  */
86
107
  normalizeFormData?: boolean;
108
+ /**
109
+ * Called when an error occurs in the handler
110
+ */
111
+ onError?: (
112
+ opts: ErrorHandlerOptions<TInstance['_config']['$types']['ctx']>,
113
+ ) => void;
114
+
115
+ /**
116
+ * Rethrow errors that should be handled by Next.js
117
+ * @default true
118
+ */
119
+ rethrowNextErrors?: boolean;
87
120
  },
88
121
  ) {
89
122
  const config = t._config;
90
- const { normalizeFormData = true, createContext } = opts;
123
+ const {
124
+ normalizeFormData = true,
125
+ createContext,
126
+ rethrowNextErrors = true,
127
+ } = opts;
91
128
 
92
129
  const transformer = config.transformer;
93
130
 
@@ -100,11 +137,11 @@ export function experimental_createServerActionHandler<
100
137
  return async function actionHandler(
101
138
  rawInput: FormData | inferProcedureInput<TProc>,
102
139
  ) {
103
- const ctx: TInstance['_config']['$types']['ctx'] | undefined = undefined;
140
+ let ctx: TInstance['_config']['$types']['ctx'] | undefined = undefined;
104
141
  try {
105
- const ctx = await createContext();
142
+ ctx = (await createContext?.()) ?? {};
106
143
  if (normalizeFormData && isFormData(rawInput)) {
107
- // Normalizes formdata so we can use `z.object({})` etc on the server
144
+ // Normalizes FormData so we can use `z.object({})` etc on the server
108
145
  try {
109
146
  rawInput = formDataToObject(rawInput);
110
147
  } catch {
@@ -117,13 +154,15 @@ export function experimental_createServerActionHandler<
117
154
  rawInput = transformer.input.deserialize(rawInput);
118
155
  }
119
156
 
120
- const data = await proc({
121
- input: undefined,
122
- ctx,
123
- path: 'serverAction',
124
- getRawInput: async () => rawInput,
125
- type: proc._def.type,
126
- });
157
+ const data = proc._def.experimental_caller
158
+ ? await proc(rawInput)
159
+ : await proc({
160
+ input: undefined,
161
+ ctx,
162
+ path: '',
163
+ getRawInput: async () => rawInput,
164
+ type: proc._def.type,
165
+ });
127
166
 
128
167
  const transformedJSON = transformTRPCResponse(config, {
129
168
  result: {
@@ -133,17 +172,26 @@ export function experimental_createServerActionHandler<
133
172
  return transformedJSON;
134
173
  } catch (cause) {
135
174
  const error = getTRPCErrorFromUnknown(cause);
175
+
176
+ opts.onError?.({
177
+ ctx,
178
+ error,
179
+ input: rawInput,
180
+ path: '',
181
+ type: proc._def.type,
182
+ });
183
+
184
+ rethrowNextErrors && throwNextErrors(error);
185
+
136
186
  const shape = getErrorShape({
137
187
  config,
138
188
  ctx,
139
189
  error,
140
190
  input: rawInput,
141
- path: 'serverAction',
191
+ path: '',
142
192
  type: proc._def.type,
143
193
  });
144
194
 
145
- // TODO: send the right HTTP header?!
146
-
147
195
  return transformTRPCResponse(t._config, {
148
196
  error: shape,
149
197
  });