Skip to content

Commit 5145d6a

Browse files
authored
Merge pull request #1552 from microsoft/chore/add_3xx_tests
fix: handle 3XX responses
2 parents d806e90 + 856de64 commit 5145d6a

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

packages/http/fetch/src/fetchRequestAdapter.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,11 @@ export class FetchRequestAdapter implements RequestAdapter {
390390
};
391391
public static readonly errorMappingFoundAttributeName = "com.microsoft.kiota.error.mapping_found";
392392
public static readonly errorBodyFoundAttributeName = "com.microsoft.kiota.error.body_found";
393+
private static readonly locationHeaderName = "Location";
393394
private readonly throwIfFailedResponse = (response: Response, errorMappings: ErrorMappings | undefined, spanForAttributes: Span): Promise<void> => {
394395
return trace.getTracer(this.observabilityOptions.getTracerInstrumentationName()).startActiveSpan("throwIfFailedResponse", async (span) => {
395396
try {
396-
if (response.ok) return;
397+
if (response.ok || (response.status >= 300 && response.status < 400 && !response.headers.has(FetchRequestAdapter.locationHeaderName))) return;
397398

398399
spanForAttributes.setStatus({
399400
code: SpanStatusCode.ERROR,

packages/http/fetch/test/common/fetchRequestAdapter.ts

+45
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,49 @@ describe("FetchRequestAdapter.ts", () => {
208208
}
209209
});
210210
});
211+
describe("returns null on 3XX responses without location header", () => {
212+
it("should not throw API error when 3XX response with no Location header", async () => {
213+
const mockHttpClient = new HttpClient();
214+
mockHttpClient.executeFetch = async (url: string, requestInit: RequestInit, requestOptions?: Record<string, RequestOption>) => {
215+
const response = new Response(null, {
216+
status: 304,
217+
} as ResponseInit);
218+
response.headers.set("Content-Type", "application/json");
219+
return Promise.resolve(response);
220+
};
221+
const mockFactory = new MockParseNodeFactory(new MockParseNode({}));
222+
const requestAdapter = new FetchRequestAdapter(new AnonymousAuthenticationProvider(), mockFactory, undefined, mockHttpClient);
223+
const requestInformation = new RequestInformation();
224+
requestInformation.URL = "https://www.example.com";
225+
requestInformation.httpMethod = HttpMethod.GET;
226+
try {
227+
const result = await requestAdapter.send(requestInformation, createMockEntityFromDiscriminatorValue, undefined);
228+
assert.isUndefined(result);
229+
} catch (error) {
230+
assert.fail("Should not throw an error");
231+
}
232+
});
233+
it("should throw API error when 3XX response with a Location header", async () => {
234+
const mockHttpClient = new HttpClient();
235+
mockHttpClient.executeFetch = async (url: string, requestInit: RequestInit, requestOptions?: Record<string, RequestOption>) => {
236+
const response = new Response(null, {
237+
status: 304,
238+
} as ResponseInit);
239+
response.headers.set("Content-Type", "application/json");
240+
response.headers.set("Location", "xxx");
241+
return Promise.resolve(response);
242+
};
243+
const mockFactory = new MockParseNodeFactory(new MockParseNode({}));
244+
const requestAdapter = new FetchRequestAdapter(new AnonymousAuthenticationProvider(), mockFactory, undefined, mockHttpClient);
245+
const requestInformation = new RequestInformation();
246+
requestInformation.URL = "https://www.example.com";
247+
requestInformation.httpMethod = HttpMethod.GET;
248+
try {
249+
await requestAdapter.sendNoResponseContent(requestInformation, undefined);
250+
assert.fail("Should have thrown an error");
251+
} catch (error) {
252+
assert.equal(error.responseStatusCode, 304);
253+
}
254+
});
255+
});
211256
});

0 commit comments

Comments
 (0)