202 lines
6.3 KiB
JavaScript
202 lines
6.3 KiB
JavaScript
|
var AWS = require('./core');
|
||
|
var inherit = AWS.util.inherit;
|
||
|
var jmespath = require('jmespath');
|
||
|
|
||
|
/**
|
||
|
* This class encapsulates the response information
|
||
|
* from a service request operation sent through {AWS.Request}.
|
||
|
* The response object has two main properties for getting information
|
||
|
* back from a request:
|
||
|
*
|
||
|
* ## The `data` property
|
||
|
*
|
||
|
* The `response.data` property contains the serialized object data
|
||
|
* retrieved from the service request. For instance, for an
|
||
|
* Amazon DynamoDB `listTables` method call, the response data might
|
||
|
* look like:
|
||
|
*
|
||
|
* ```
|
||
|
* > resp.data
|
||
|
* { TableNames:
|
||
|
* [ 'table1', 'table2', ... ] }
|
||
|
* ```
|
||
|
*
|
||
|
* The `data` property can be null if an error occurs (see below).
|
||
|
*
|
||
|
* ## The `error` property
|
||
|
*
|
||
|
* In the event of a service error (or transfer error), the
|
||
|
* `response.error` property will be filled with the given
|
||
|
* error data in the form:
|
||
|
*
|
||
|
* ```
|
||
|
* { code: 'SHORT_UNIQUE_ERROR_CODE',
|
||
|
* message: 'Some human readable error message' }
|
||
|
* ```
|
||
|
*
|
||
|
* In the case of an error, the `data` property will be `null`.
|
||
|
* Note that if you handle events that can be in a failure state,
|
||
|
* you should always check whether `response.error` is set
|
||
|
* before attempting to access the `response.data` property.
|
||
|
*
|
||
|
* @!attribute data
|
||
|
* @readonly
|
||
|
* @!group Data Properties
|
||
|
* @note Inside of a {AWS.Request~httpData} event, this
|
||
|
* property contains a single raw packet instead of the
|
||
|
* full de-serialized service response.
|
||
|
* @return [Object] the de-serialized response data
|
||
|
* from the service.
|
||
|
*
|
||
|
* @!attribute error
|
||
|
* An structure containing information about a service
|
||
|
* or networking error.
|
||
|
* @readonly
|
||
|
* @!group Data Properties
|
||
|
* @note This attribute is only filled if a service or
|
||
|
* networking error occurs.
|
||
|
* @return [Error]
|
||
|
* * code [String] a unique short code representing the
|
||
|
* error that was emitted.
|
||
|
* * message [String] a longer human readable error message
|
||
|
* * retryable [Boolean] whether the error message is
|
||
|
* retryable.
|
||
|
* * statusCode [Numeric] in the case of a request that reached the service,
|
||
|
* this value contains the response status code.
|
||
|
* * time [Date] the date time object when the error occurred.
|
||
|
* * hostname [String] set when a networking error occurs to easily
|
||
|
* identify the endpoint of the request.
|
||
|
* * region [String] set when a networking error occurs to easily
|
||
|
* identify the region of the request.
|
||
|
*
|
||
|
* @!attribute requestId
|
||
|
* @readonly
|
||
|
* @!group Data Properties
|
||
|
* @return [String] the unique request ID associated with the response.
|
||
|
* Log this value when debugging requests for AWS support.
|
||
|
*
|
||
|
* @!attribute retryCount
|
||
|
* @readonly
|
||
|
* @!group Operation Properties
|
||
|
* @return [Integer] the number of retries that were
|
||
|
* attempted before the request was completed.
|
||
|
*
|
||
|
* @!attribute redirectCount
|
||
|
* @readonly
|
||
|
* @!group Operation Properties
|
||
|
* @return [Integer] the number of redirects that were
|
||
|
* followed before the request was completed.
|
||
|
*
|
||
|
* @!attribute httpResponse
|
||
|
* @readonly
|
||
|
* @!group HTTP Properties
|
||
|
* @return [AWS.HttpResponse] the raw HTTP response object
|
||
|
* containing the response headers and body information
|
||
|
* from the server.
|
||
|
*
|
||
|
* @see AWS.Request
|
||
|
*/
|
||
|
AWS.Response = inherit({
|
||
|
|
||
|
/**
|
||
|
* @api private
|
||
|
*/
|
||
|
constructor: function Response(request) {
|
||
|
this.request = request;
|
||
|
this.data = null;
|
||
|
this.error = null;
|
||
|
this.retryCount = 0;
|
||
|
this.redirectCount = 0;
|
||
|
this.httpResponse = new AWS.HttpResponse();
|
||
|
if (request) {
|
||
|
this.maxRetries = request.service.numRetries();
|
||
|
this.maxRedirects = request.service.config.maxRedirects;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Creates a new request for the next page of response data, calling the
|
||
|
* callback with the page data if a callback is provided.
|
||
|
*
|
||
|
* @callback callback function(err, data)
|
||
|
* Called when a page of data is returned from the next request.
|
||
|
*
|
||
|
* @param err [Error] an error object, if an error occurred in the request
|
||
|
* @param data [Object] the next page of data, or null, if there are no
|
||
|
* more pages left.
|
||
|
* @return [AWS.Request] the request object for the next page of data
|
||
|
* @return [null] if no callback is provided and there are no pages left
|
||
|
* to retrieve.
|
||
|
* @since v1.4.0
|
||
|
*/
|
||
|
nextPage: function nextPage(callback) {
|
||
|
var config;
|
||
|
var service = this.request.service;
|
||
|
var operation = this.request.operation;
|
||
|
try {
|
||
|
config = service.paginationConfig(operation, true);
|
||
|
} catch (e) { this.error = e; }
|
||
|
|
||
|
if (!this.hasNextPage()) {
|
||
|
if (callback) callback(this.error, null);
|
||
|
else if (this.error) throw this.error;
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
var params = AWS.util.copy(this.request.params);
|
||
|
if (!this.nextPageTokens) {
|
||
|
return callback ? callback(null, null) : null;
|
||
|
} else {
|
||
|
var inputTokens = config.inputToken;
|
||
|
if (typeof inputTokens === 'string') inputTokens = [inputTokens];
|
||
|
for (var i = 0; i < inputTokens.length; i++) {
|
||
|
params[inputTokens[i]] = this.nextPageTokens[i];
|
||
|
}
|
||
|
return service.makeRequest(this.request.operation, params, callback);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @return [Boolean] whether more pages of data can be returned by further
|
||
|
* requests
|
||
|
* @since v1.4.0
|
||
|
*/
|
||
|
hasNextPage: function hasNextPage() {
|
||
|
this.cacheNextPageTokens();
|
||
|
if (this.nextPageTokens) return true;
|
||
|
if (this.nextPageTokens === undefined) return undefined;
|
||
|
else return false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @api private
|
||
|
*/
|
||
|
cacheNextPageTokens: function cacheNextPageTokens() {
|
||
|
if (Object.prototype.hasOwnProperty.call(this, 'nextPageTokens')) return this.nextPageTokens;
|
||
|
this.nextPageTokens = undefined;
|
||
|
|
||
|
var config = this.request.service.paginationConfig(this.request.operation);
|
||
|
if (!config) return this.nextPageTokens;
|
||
|
|
||
|
this.nextPageTokens = null;
|
||
|
if (config.moreResults) {
|
||
|
if (!jmespath.search(this.data, config.moreResults)) {
|
||
|
return this.nextPageTokens;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var exprs = config.outputToken;
|
||
|
if (typeof exprs === 'string') exprs = [exprs];
|
||
|
AWS.util.arrayEach.call(this, exprs, function (expr) {
|
||
|
var output = jmespath.search(this.data, expr);
|
||
|
if (output) {
|
||
|
this.nextPageTokens = this.nextPageTokens || [];
|
||
|
this.nextPageTokens.push(output);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return this.nextPageTokens;
|
||
|
}
|
||
|
|
||
|
});
|