@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
121 lines • 5.96 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Constants } from "../common/constants.js";
import { StatusCodes, SubStatusCodes } from "../common/statusCodes.js";
import { ErrorResponse } from "../index.js";
import { isSuccessStatusCode } from "../utils/batch.js";
/**
* Represents a batch response for bulk request.
* @hidden
*/
export class BulkResponse {
statusCode;
subStatusCode;
headers;
operations;
results = [];
diagnostics;
constructor(statusCode, subStatusCode, headers, operations) {
this.statusCode = statusCode;
this.subStatusCode = subStatusCode;
this.headers = headers;
this.operations = operations;
}
/**
* Generate empty response object
*/
static createEmptyResponse(operations, statusCode, subStatusCode, headers) {
const bulkResponse = new BulkResponse(statusCode, subStatusCode, headers, operations);
bulkResponse.createAndPopulateResults(operations, 0, new ErrorResponse());
return bulkResponse;
}
/**
* static method to create BulkResponse from Response object
*/
static fromResponseMessage(responseMessage, operations) {
// Create and populate the response object
let bulkResponse = this.populateFromResponse(responseMessage, operations);
if (!bulkResponse.results || bulkResponse.results.length !== operations.length) {
// Server should be guaranteeing number of results equal to operations when
// batch request is successful - so fail as InternalServerError if this is not the case.
if (isSuccessStatusCode(responseMessage.code)) {
bulkResponse = new BulkResponse(StatusCodes.InternalServerError, SubStatusCodes.Unknown, responseMessage.headers, operations);
}
// When the overall response status code is TooManyRequests, propagate the RetryAfter into the individual operations.
let retryAfterMilliseconds = 0;
if (responseMessage.code === StatusCodes.TooManyRequests) {
const retryAfter = responseMessage.headers?.[Constants.HttpHeaders.RetryAfterInMs];
retryAfterMilliseconds = !retryAfter || isNaN(Number(retryAfter)) ? 0 : Number(retryAfter);
}
bulkResponse.createAndPopulateResults(operations, retryAfterMilliseconds, responseMessage);
}
return bulkResponse;
}
static populateFromResponse(responseMessage, operations) {
const results = [];
if (responseMessage.result) {
for (let i = 0; i < operations.length; i++) {
const itemResponse = responseMessage.result[i];
if (isSuccessStatusCode(itemResponse?.statusCode)) {
const result = {
statusCode: itemResponse?.statusCode,
eTag: itemResponse?.eTag,
activityId: responseMessage.headers?.[Constants.HttpHeaders.ActivityId],
sessionToken: responseMessage.headers?.[Constants.HttpHeaders.SessionToken],
requestCharge: itemResponse?.requestCharge,
resourceBody: itemResponse?.resourceBody,
// diagnostics will be filled in Batcher dispatch to capture the complete diagnostics(e.g. decryption)
diagnostics: null,
headers: responseMessage.headers,
};
results.push(result);
}
else {
const error = new ErrorResponse();
error.code = itemResponse?.statusCode;
error.substatus = itemResponse?.subStatusCode;
error.message = itemResponse?.message;
error.requestCharge = itemResponse?.requestCharge;
error.body = itemResponse?.resourceBody;
error.headers = responseMessage.headers;
error.activityId = responseMessage.headers?.[Constants.HttpHeaders.ActivityId];
error.retryAfterInMs = itemResponse?.retryAfterMilliseconds;
error.diagnostics = responseMessage.diagnostics;
results.push(error);
}
}
}
let statusCode = responseMessage.code;
let subStatusCode = responseMessage.substatus;
if (responseMessage.code === StatusCodes.MultiStatus) {
for (const result of results) {
if (result instanceof ErrorResponse &&
result.statusCode !== StatusCodes.FailedDependency &&
result.statusCode >= StatusCodes.BadRequest) {
statusCode = typeof result.code === "number" ? result.code : Number(result.code);
subStatusCode = result.substatus;
break;
}
}
}
const bulkResponse = new BulkResponse(statusCode, subStatusCode, responseMessage.headers, operations);
bulkResponse.results = results;
return bulkResponse;
}
createAndPopulateResults(operations, retryAfterInMs, error) {
this.results = operations.map(() => {
const errorResponse = new ErrorResponse();
errorResponse.message = error.message;
errorResponse.code = this.statusCode;
errorResponse.substatus = this.subStatusCode;
errorResponse.retryAfterInMs = retryAfterInMs;
errorResponse.activityId = this.headers?.[Constants.HttpHeaders.ActivityId];
errorResponse.body = error.body;
errorResponse.diagnostics = error.diagnostics;
errorResponse.headers = this.headers;
errorResponse.requestCharge = error.requestCharge;
return errorResponse;
});
}
}
//# sourceMappingURL=BulkResponse.js.map