豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 695817f

Browse files
authored
fix: make request and response handling more robust (#846)
Closes #842
1 parent dc43ede commit 695817f

File tree

2 files changed

+78
-49
lines changed

2 files changed

+78
-49
lines changed

src/formatters/NetworkFormatter.ts

Lines changed: 36 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -50,57 +50,60 @@ export class NetworkFormatter {
5050
async #loadDetailedData(): Promise<void> {
5151
// Load Request Body
5252
if (this.#request.hasPostData()) {
53-
const data = this.#request.postData();
54-
if (data) {
55-
if (this.#options.requestFilePath) {
56-
if (!this.#options.saveFile) {
57-
throw new Error('saveFile is not provided');
58-
}
53+
let data;
54+
try {
55+
data =
56+
this.#request.postData() ?? (await this.#request.fetchPostData());
57+
} catch {
58+
// Ignore parsing errors
59+
}
60+
const requestBodyNotAvailableMessage =
61+
'<Request body not available anymore>';
62+
if (this.#options.requestFilePath) {
63+
if (!this.#options.saveFile) {
64+
throw new Error('saveFile is not provided');
65+
}
66+
if (data) {
5967
await this.#options.saveFile(
6068
Buffer.from(data),
6169
this.#options.requestFilePath,
6270
);
6371
this.#requestBodyFilePath = this.#options.requestFilePath;
6472
} else {
73+
this.#requestBody = requestBodyNotAvailableMessage;
74+
}
75+
} else {
76+
if (data) {
6577
this.#requestBody = getSizeLimitedString(
6678
data,
6779
BODY_CONTEXT_SIZE_LIMIT,
6880
);
69-
}
70-
} else {
71-
try {
72-
const fetchData = await this.#request.fetchPostData();
73-
if (fetchData) {
74-
if (this.#options.requestFilePath) {
75-
if (!this.#options.saveFile) {
76-
throw new Error('saveFile is not provided');
77-
}
78-
await this.#options.saveFile(
79-
Buffer.from(fetchData),
80-
this.#options.requestFilePath,
81-
);
82-
this.#requestBodyFilePath = this.#options.requestFilePath;
83-
} else {
84-
this.#requestBody = getSizeLimitedString(
85-
fetchData,
86-
BODY_CONTEXT_SIZE_LIMIT,
87-
);
88-
}
89-
}
90-
} catch {
91-
this.#requestBody = '<not available anymore>';
81+
} else {
82+
this.#requestBody = requestBodyNotAvailableMessage;
9283
}
9384
}
9485
}
9586

9687
// Load Response Body
9788
const response = this.#request.response();
9889
if (response) {
90+
const responseBodyNotAvailableMessage =
91+
'<Response body not available anymore>';
9992
if (this.#options.responseFilePath) {
100-
this.#responseBodyFilePath = await this.#saveResponseBodyToFile(
101-
response,
102-
this.#options.responseFilePath,
103-
);
93+
try {
94+
const buffer = await response.buffer();
95+
if (!this.#options.saveFile) {
96+
throw new Error('saveFile is not provided');
97+
}
98+
await this.#options.saveFile(buffer, this.#options.responseFilePath);
99+
this.#responseBodyFilePath = this.#options.responseFilePath;
100+
} catch {
101+
// Flatten error handling for buffer() failure and save failure
102+
}
103+
104+
if (!this.#responseBodyFilePath) {
105+
this.#responseBody = responseBodyNotAvailableMessage;
106+
}
104107
} else {
105108
this.#responseBody = await this.#getFormattedResponseBody(
106109
response,
@@ -262,22 +265,6 @@ export class NetworkFormatter {
262265
return '<not available anymore>';
263266
}
264267
}
265-
266-
async #saveResponseBodyToFile(
267-
httpResponse: HTTPResponse,
268-
filePath: string,
269-
): Promise<string> {
270-
try {
271-
const responseBuffer = await httpResponse.buffer();
272-
if (!this.#options.saveFile) {
273-
throw new Error('saveFile is not provided');
274-
}
275-
await this.#options.saveFile(responseBuffer, filePath);
276-
return filePath;
277-
} catch {
278-
return '<not available anymore>';
279-
}
280-
}
281268
}
282269

283270
function getSizeLimitedString(text: string, sizeLimit: number) {

tests/formatters/NetworkFormatter.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,48 @@ describe('NetworkFormatter', () => {
328328
assert.ok(result.includes(`Saved to ${reqPath}.`));
329329
assert.ok(result.includes(`Saved to ${resPath}.`));
330330
});
331+
332+
it('handles missing bodies with filepath', async () => {
333+
const request = {
334+
method: () => 'POST',
335+
url: () => 'http://example.com',
336+
headers: () => ({}),
337+
hasPostData: () => true, // Claim we have data
338+
postData: () => null, // But returns null
339+
response: () => ({
340+
status: () => 200,
341+
headers: () => ({}),
342+
buffer: async () => {
343+
throw new Error('Body not available');
344+
},
345+
}),
346+
failure: () => null,
347+
redirectChain: () => [],
348+
fetchPostData: async () => {
349+
throw new Error('Body not available');
350+
},
351+
} as unknown as HTTPRequest;
352+
353+
const reqPath = join(tmpDir, 'req_missing.txt');
354+
const resPath = join(tmpDir, 'res_missing.txt');
355+
356+
const formatter = await NetworkFormatter.from(request, {
357+
fetchData: true,
358+
requestFilePath: reqPath,
359+
responseFilePath: resPath,
360+
saveFile: async (data, filename) => {
361+
await writeFile(filename, data);
362+
return {filename};
363+
},
364+
});
365+
366+
const result = formatter.toStringDetailed();
367+
assert.ok(
368+
result.includes(
369+
`### Response Body\n<Response body not available anymore>`,
370+
),
371+
);
372+
});
331373
});
332374

333375
describe('toJSON', () => {

0 commit comments

Comments
 (0)