in sdk/core/core-client/src/deserializationPolicy.ts [226:323]
function handleErrorResponse(
parsedResponse: FullOperationResponse,
operationSpec: OperationSpec,
responseSpec: OperationResponseMap | undefined,
options: RequiredSerializerOptions,
): { error: RestError | null; shouldReturnResponse: boolean } {
const isSuccessByStatus = 200 <= parsedResponse.status && parsedResponse.status < 300;
const isExpectedStatusCode: boolean = isOperationSpecEmpty(operationSpec)
? isSuccessByStatus
: !!responseSpec;
if (isExpectedStatusCode) {
if (responseSpec) {
if (!responseSpec.isError) {
return { error: null, shouldReturnResponse: false };
}
} else {
return { error: null, shouldReturnResponse: false };
}
}
const errorResponseSpec = responseSpec ?? operationSpec.responses.default;
const initialErrorMessage = parsedResponse.request.streamResponseStatusCodes?.has(
parsedResponse.status,
)
? `Unexpected status code: ${parsedResponse.status}`
: (parsedResponse.bodyAsText as string);
const error = new RestError(initialErrorMessage, {
statusCode: parsedResponse.status,
request: parsedResponse.request,
response: parsedResponse,
});
// If the item failed but there's no error spec or default spec to deserialize the error,
// and the parsed body doesn't look like an error object,
// we should fail so we just throw the parsed response
if (
!errorResponseSpec &&
!(parsedResponse.parsedBody?.error?.code && parsedResponse.parsedBody?.error?.message)
) {
throw error;
}
const defaultBodyMapper = errorResponseSpec?.bodyMapper;
const defaultHeadersMapper = errorResponseSpec?.headersMapper;
try {
// If error response has a body, try to deserialize it using default body mapper.
// Then try to extract error code & message from it
if (parsedResponse.parsedBody) {
const parsedBody = parsedResponse.parsedBody;
let deserializedError;
if (defaultBodyMapper) {
let valueToDeserialize: any = parsedBody;
if (operationSpec.isXML && defaultBodyMapper.type.name === MapperTypeNames.Sequence) {
valueToDeserialize = [];
const elementName = defaultBodyMapper.xmlElementName;
if (typeof parsedBody === "object" && elementName) {
valueToDeserialize = parsedBody[elementName];
}
}
deserializedError = operationSpec.serializer.deserialize(
defaultBodyMapper,
valueToDeserialize,
"error.response.parsedBody",
options,
);
}
const internalError: any = parsedBody.error || deserializedError || parsedBody;
error.code = internalError.code;
if (internalError.message) {
error.message = internalError.message;
}
if (defaultBodyMapper) {
(error.response! as FullOperationResponse).parsedBody = deserializedError;
}
}
// If error response has headers, try to deserialize it using default header mapper
if (parsedResponse.headers && defaultHeadersMapper) {
(error.response! as FullOperationResponse).parsedHeaders =
operationSpec.serializer.deserialize(
defaultHeadersMapper,
parsedResponse.headers.toJSON(),
"operationRes.parsedHeaders",
);
}
} catch (defaultError: any) {
error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody - "${parsedResponse.bodyAsText}" for the default response.`;
}
return { error, shouldReturnResponse: false };
}