@@ -4,6 +4,7 @@ import type { UrlAndMap } from "source-map-support";
4
4
import { z } from "zod" ;
5
5
import { Request , Response } from "../../../http" ;
6
6
import { Log } from "../../../shared" ;
7
+ import { getUserServiceName } from "../constants" ;
7
8
import {
8
9
SourceOptions ,
9
10
contentsToString ,
@@ -13,33 +14,31 @@ import { getSourceMapper } from "./sourcemap";
13
14
14
15
// Subset of core worker options that define Worker source code.
15
16
// These are the possible cases, and corresponding reported source files in
16
- // workerd stack traces. Note that all service-worker scripts will be called
17
- // "worker.js" in `workerd`, so we can't differentiate between multiple workers.
18
- // TODO: see if we can add a service-worker script path config option to handle
19
- // case (i)[i]
17
+ // workerd stack traces.
20
18
//
21
19
// Single Worker:
22
- // (a) { script: "<contents>" } -> "worker.js "
23
- // (b) { script: "<contents>", modules: true } -> "<script:0>"
24
- // (c) { script: "<contents>", scriptPath: "<path>" } -> "worker.js "
25
- // (d) { script: "<contents>", scriptPath: "<path>", modules: true } -> "<path>"
26
- // (e) { scriptPath: "<path>" } -> "worker.js "
27
- // (f) { scriptPath: "<path>", modules: true } -> "<path>"
20
+ // (a) { script: "<contents>" } -> "core:user: "
21
+ // (b) { script: "<contents>", modules: true } -> "<script:0>"
22
+ // (c) { script: "<contents>", scriptPath: "<path>" } -> "core:user: "
23
+ // (d) { script: "<contents>", scriptPath: "<path>", modules: true } -> "<path>"
24
+ // (e) { scriptPath: "<path>" } -> "core:user: "
25
+ // (f) { scriptPath: "<path>", modules: true } -> "<path>"
28
26
// (g) { modules: [
29
- // [i] { ..., path: "<path:0>", contents: "<contents:0>" }, -> "<path:0>" relative to cwd
30
- // [ii] { ..., path: "<path:1>" }, -> "<path:1>" relative to cwd
27
+ // [i] { ..., path: "<path:0>", contents: "<contents:0>" }, -> "<path:0>" relative to cwd
28
+ // [ii] { ..., path: "<path:1>" }, -> "<path:1>" relative to cwd
31
29
// ] }
32
30
// (h) { modulesRoot: "<root>", modules: [
33
- // [i] { ..., path: "<path:0>", contents: "<contents:0>" }, -> "<path:0>" relative to "<root>"
34
- // [ii] { ..., path: "<path:1>" }, -> "<path:1>" relative to "<root>"
31
+ // [i] { ..., path: "<path:0>", contents: "<contents:0>" }, -> "<path:0>" relative to "<root>"
32
+ // [ii] { ..., path: "<path:1>" }, -> "<path:1>" relative to "<root>"
35
33
// ] }
36
34
//
37
35
// Multiple Workers (array of `SourceOptions`):
38
- // (i) [ (note cannot differentiate "worker.js"s)
39
- // [i] { script: "<contents:0>" }, -> "worker.js"
40
- // { script: "<contents:1>" }, -> "worker.js"
41
- // { script: "<contents:2>", scriptPath: "<path:2>" }, -> "worker.js"
42
- // [ii] { script: "<contents:3>", modules: true }, -> "<script:3>"
36
+ // (i) [
37
+ // [i] { script: "<contents:0>" }, -> "core:user:"
38
+ // [ii] { name: "a", script: "<contents:1>" }, -> "core:user:a"
39
+ // [iii] { name: "b", script: "<contents:2>", scriptPath: "<path:2>" }, -> "core:user:b"
40
+ // [iv] { name: "c", scriptPath: "<path:3>" }, -> "core:user:c"
41
+ // [v] { script: "<contents:3>", modules: true }, -> "<script:3>"
43
42
// ]
44
43
//
45
44
@@ -59,11 +58,13 @@ function maybeGetDiskFile(filePath: string): SourceFile | undefined {
59
58
}
60
59
}
61
60
61
+ export type NameSourceOptions = SourceOptions & { name ?: string } ;
62
+
62
63
// Try to extract the path and contents of a `file` reported in a JavaScript
63
64
// stack-trace. See the `SourceOptions` comment for examples of what these look
64
65
// like.
65
66
function maybeGetFile (
66
- workerSrcOpts : SourceOptions [ ] ,
67
+ workerSrcOpts : NameSourceOptions [ ] ,
67
68
file : string
68
69
) : SourceFile | undefined {
69
70
// Resolve file relative to current working directory
@@ -111,7 +112,7 @@ function maybeGetFile(
111
112
}
112
113
}
113
114
114
- // Cases: (b), (i)[ii ]
115
+ // Cases: (b), (i)[v ]
115
116
// 3. If file looks like "<script:n>", and the `n`th worker has a custom
116
117
// `script`, use that.
117
118
const workerIndex = maybeGetStringScriptPathIndex ( file ) ;
@@ -122,22 +123,15 @@ function maybeGetFile(
122
123
}
123
124
}
124
125
125
- // Cases: (a), (c), (e)
126
- // 4. If there is a single worker defined with `modules` disabled, the
127
- // file is "worker.js", then...
128
- //
129
- // Note: can't handle case (i)[i], as cannot distinguish between multiple
130
- // "worker.js"s, hence the check for a single worker. We'd rather be
131
- // conservative and return no contents (and therefore no source code in the
132
- // error page) over incorrect ones.
133
- if ( workerSrcOpts . length === 1 ) {
134
- const srcOpts = workerSrcOpts [ 0 ] ;
126
+ // Cases: (a), (c), (e), (i)[i], (i)[ii], (i)[iii], (i)[iv]
127
+ // 4. If `file` is the name of a service, use that services' source.
128
+ for ( const srcOpts of workerSrcOpts ) {
135
129
if (
136
- file === "worker.js" &&
130
+ file === getUserServiceName ( srcOpts . name ) &&
137
131
( srcOpts . modules === undefined || srcOpts . modules === false )
138
132
) {
139
133
if ( "script" in srcOpts && srcOpts . script !== undefined ) {
140
- // Cases: (a), (c)
134
+ // Cases: (a), (c), (i)[i], (i)[ii], (i)[iii]
141
135
// ...if a custom `script` is defined, use that, with the defined
142
136
// `scriptPath` if any (Case (c))
143
137
return {
@@ -148,7 +142,7 @@ function maybeGetFile(
148
142
contents : srcOpts . script ,
149
143
} ;
150
144
} else if ( srcOpts . scriptPath !== undefined ) {
151
- // Case: (e)
145
+ // Case: (e), (i)[iv]
152
146
// ...otherwise, if a `scriptPath` is defined, use that
153
147
return maybeGetDiskFile ( path . resolve ( srcOpts . scriptPath ) ) ;
154
148
}
@@ -160,7 +154,10 @@ function maybeGetFile(
160
154
return maybeGetDiskFile ( filePath ) ;
161
155
}
162
156
163
- function getSourceMappedStack ( workerSrcOpts : SourceOptions [ ] , error : Error ) {
157
+ function getSourceMappedStack (
158
+ workerSrcOpts : NameSourceOptions [ ] ,
159
+ error : Error
160
+ ) {
164
161
// This function needs to match the signature of the `retrieveSourceMap`
165
162
// option from the "source-map-support" package.
166
163
function retrieveSourceMap ( file : string ) : UrlAndMap | null {
@@ -220,7 +217,7 @@ const ALLOWED_ERROR_SUBCLASS_CONSTRUCTORS: StandardErrorConstructor[] = [
220
217
URIError ,
221
218
] ;
222
219
export function reviveError (
223
- workerSrcOpts : SourceOptions [ ] ,
220
+ workerSrcOpts : NameSourceOptions [ ] ,
224
221
jsonError : JsonError
225
222
) : Error {
226
223
// At a high level, this function takes a JSON-serialisable representation of
@@ -262,7 +259,7 @@ export function reviveError(
262
259
263
260
export async function handlePrettyErrorRequest (
264
261
log : Log ,
265
- workerSrcOpts : SourceOptions [ ] ,
262
+ workerSrcOpts : NameSourceOptions [ ] ,
266
263
request : Request
267
264
) : Promise < Response > {
268
265
// Parse and validate the error we've been given from user code
0 commit comments