Skip to content

Commit 69180cd

Browse files
authored
rename error (#5549)
1 parent 202b8e3 commit 69180cd

File tree

2 files changed

+80
-67
lines changed

2 files changed

+80
-67
lines changed

packages/services/cdn-worker/src/artifact-storage-reader.ts

Lines changed: 70 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -122,74 +122,71 @@ export class ArtifactStorageReader {
122122
},
123123
})
124124
.catch(err => {
125-
if (this.s3Mirror) {
126-
// Use two AbortSignals to avoid a situation
127-
// where Response.body is consumed,
128-
// but the request was aborted after being resolved.
129-
// When a fetch call is resolved successfully,
130-
// but a shared AbortSignal.cancel() is called for two fetches,
131-
// it causes an exception (can't read a response from an aborted requests)
132-
// when Response.body is consumed.
133-
const primaryController = new AbortController();
134-
const mirrorController = new AbortController();
135-
136-
function abortOtherRequest(ctrl: AbortController) {
137-
return (res: Response) => {
138-
// abort other pending request
139-
const error = new Error('Another request won the race.');
140-
// change the name so we have some metrics for this on our analytics dashboard
141-
error.name = 'AbortError';
142-
ctrl.abort(error);
143-
144-
return res;
145-
};
146-
}
147-
148-
// Wait for the first successful response
149-
// or reject if both requests fail
150-
return Promise.any([
151-
this.s3.client
152-
.fetch([this.s3.endpoint, this.s3.bucketName, args.key].join('/'), {
153-
method: args.method,
154-
headers: args.headers,
155-
aws: {
156-
signQuery: true,
157-
},
158-
timeout: this.timeout,
159-
signal: primaryController.signal,
160-
isResponseOk: response =>
161-
response.status === 200 || response.status === 304 || response.status === 404,
162-
onAttempt: args1 => {
163-
args.onAttempt({
164-
...args1,
165-
isMirror: false,
166-
});
167-
},
168-
})
169-
.then(abortOtherRequest(mirrorController)),
170-
this.s3Mirror.client
171-
.fetch([this.s3Mirror.endpoint, this.s3Mirror.bucketName, args.key].join('/'), {
172-
method: args.method,
173-
headers: args.headers,
174-
aws: {
175-
signQuery: true,
176-
},
177-
timeout: this.timeout,
178-
signal: mirrorController.signal,
179-
isResponseOk: response =>
180-
response.status === 200 || response.status === 304 || response.status === 404,
181-
onAttempt: args1 => {
182-
args.onAttempt({
183-
...args1,
184-
isMirror: true,
185-
});
186-
},
187-
})
188-
.then(abortOtherRequest(primaryController)),
189-
]);
125+
if (!this.s3Mirror) {
126+
return Promise.reject(err);
127+
}
128+
// Use two AbortSignals to avoid a situation
129+
// where Response.body is consumed,
130+
// but the request was aborted after being resolved.
131+
// When a fetch call is resolved successfully,
132+
// but a shared AbortSignal.cancel() is called for two fetches,
133+
// it causes an exception (can't read a response from an aborted requests)
134+
// when Response.body is consumed.
135+
const primaryController = new AbortController();
136+
const mirrorController = new AbortController();
137+
138+
function abortOtherRequest(ctrl: AbortController) {
139+
return (res: Response) => {
140+
// abort other pending request
141+
const error = new PendingRequestAbortedError();
142+
ctrl.abort(error);
143+
144+
return res;
145+
};
190146
}
191147

192-
return Promise.reject(err);
148+
// Wait for the first successful response
149+
// or reject if both requests fail
150+
return Promise.any([
151+
this.s3.client
152+
.fetch([this.s3.endpoint, this.s3.bucketName, args.key].join('/'), {
153+
method: args.method,
154+
headers: args.headers,
155+
aws: {
156+
signQuery: true,
157+
},
158+
timeout: this.timeout,
159+
signal: primaryController.signal,
160+
isResponseOk: response =>
161+
response.status === 200 || response.status === 304 || response.status === 404,
162+
onAttempt: args1 => {
163+
args.onAttempt({
164+
...args1,
165+
isMirror: false,
166+
});
167+
},
168+
})
169+
.then(abortOtherRequest(mirrorController)),
170+
this.s3Mirror.client
171+
.fetch([this.s3Mirror.endpoint, this.s3Mirror.bucketName, args.key].join('/'), {
172+
method: args.method,
173+
headers: args.headers,
174+
aws: {
175+
signQuery: true,
176+
},
177+
timeout: this.timeout,
178+
signal: mirrorController.signal,
179+
isResponseOk: response =>
180+
response.status === 200 || response.status === 304 || response.status === 404,
181+
onAttempt: args1 => {
182+
args.onAttempt({
183+
...args1,
184+
isMirror: true,
185+
});
186+
},
187+
})
188+
.then(abortOtherRequest(primaryController)),
189+
]);
193190
});
194191
}
195192

@@ -380,3 +377,10 @@ export class ArtifactStorageReader {
380377
return response;
381378
}
382379
}
380+
381+
class PendingRequestAbortedError extends Error {
382+
constructor() {
383+
super('Pending request was aborted');
384+
this.name = 'PendingRequestAbortedError';
385+
}
386+
}

packages/services/cdn-worker/src/aws.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ export class AwsClient {
180180
retryCounter === maximumRetryCount
181181
) {
182182
if (init.isResponseOk && !init.isResponseOk(response)) {
183-
throw new Error(`Response not okay, status: ${response.status}`);
183+
throw new ResponseNotOkayError(response);
184184
}
185185

186186
return response;
@@ -556,3 +556,12 @@ function anySignal(signals: Array<AbortSignal | undefined>) {
556556

557557
return controller.signal;
558558
}
559+
560+
class ResponseNotOkayError extends Error {
561+
response: Response;
562+
563+
constructor(response: Response) {
564+
super(`Response not okay, status: ${response.status}`);
565+
this.response = response;
566+
}
567+
}

0 commit comments

Comments
 (0)