UNPKG

6.47 kBJavaScriptView Raw
1var AWS = require('./core');
2var inherit = AWS.util.inherit;
3var jmespath = require('jmespath');
4
5/**
6 * This class encapsulates the response information
7 * from a service request operation sent through {AWS.Request}.
8 * The response object has two main properties for getting information
9 * back from a request:
10 *
11 * ## The `data` property
12 *
13 * The `response.data` property contains the serialized object data
14 * retrieved from the service request. For instance, for an
15 * Amazon DynamoDB `listTables` method call, the response data might
16 * look like:
17 *
18 * ```
19 * > resp.data
20 * { TableNames:
21 * [ 'table1', 'table2', ... ] }
22 * ```
23 *
24 * The `data` property can be null if an error occurs (see below).
25 *
26 * ## The `error` property
27 *
28 * In the event of a service error (or transfer error), the
29 * `response.error` property will be filled with the given
30 * error data in the form:
31 *
32 * ```
33 * { code: 'SHORT_UNIQUE_ERROR_CODE',
34 * message: 'Some human readable error message' }
35 * ```
36 *
37 * In the case of an error, the `data` property will be `null`.
38 * Note that if you handle events that can be in a failure state,
39 * you should always check whether `response.error` is set
40 * before attempting to access the `response.data` property.
41 *
42 * @!attribute data
43 * @readonly
44 * @!group Data Properties
45 * @note Inside of a {AWS.Request~httpData} event, this
46 * property contains a single raw packet instead of the
47 * full de-serialized service response.
48 * @return [Object] the de-serialized response data
49 * from the service.
50 *
51 * @!attribute error
52 * An structure containing information about a service
53 * or networking error.
54 * @readonly
55 * @!group Data Properties
56 * @note This attribute is only filled if a service or
57 * networking error occurs.
58 * @return [Error]
59 * * code [String] a unique short code representing the
60 * error that was emitted.
61 * * message [String] a longer human readable error message
62 * * retryable [Boolean] whether the error message is
63 * retryable.
64 * * statusCode [Numeric] in the case of a request that reached the service,
65 * this value contains the response status code.
66 * * time [Date] the date time object when the error occurred.
67 * * hostname [String] set when a networking error occurs to easily
68 * identify the endpoint of the request.
69 * * region [String] set when a networking error occurs to easily
70 * identify the region of the request.
71 *
72 * @!attribute requestId
73 * @readonly
74 * @!group Data Properties
75 * @return [String] the unique request ID associated with the response.
76 * Log this value when debugging requests for AWS support.
77 *
78 * @!attribute retryCount
79 * @readonly
80 * @!group Operation Properties
81 * @return [Integer] the number of retries that were
82 * attempted before the request was completed.
83 *
84 * @!attribute redirectCount
85 * @readonly
86 * @!group Operation Properties
87 * @return [Integer] the number of redirects that were
88 * followed before the request was completed.
89 *
90 * @!attribute httpResponse
91 * @readonly
92 * @!group HTTP Properties
93 * @return [AWS.HttpResponse] the raw HTTP response object
94 * containing the response headers and body information
95 * from the server.
96 *
97 * @see AWS.Request
98 */
99AWS.Response = inherit({
100
101 /**
102 * @api private
103 */
104 constructor: function Response(request) {
105 this.request = request;
106 this.data = null;
107 this.error = null;
108 this.retryCount = 0;
109 this.redirectCount = 0;
110 this.httpResponse = new AWS.HttpResponse();
111 if (request) {
112 this.maxRetries = request.service.numRetries();
113 this.maxRedirects = request.service.config.maxRedirects;
114 }
115 },
116
117 /**
118 * Creates a new request for the next page of response data, calling the
119 * callback with the page data if a callback is provided.
120 *
121 * @callback callback function(err, data)
122 * Called when a page of data is returned from the next request.
123 *
124 * @param err [Error] an error object, if an error occurred in the request
125 * @param data [Object] the next page of data, or null, if there are no
126 * more pages left.
127 * @return [AWS.Request] the request object for the next page of data
128 * @return [null] if no callback is provided and there are no pages left
129 * to retrieve.
130 * @since v1.4.0
131 */
132 nextPage: function nextPage(callback) {
133 var config;
134 var service = this.request.service;
135 var operation = this.request.operation;
136 try {
137 config = service.paginationConfig(operation, true);
138 } catch (e) { this.error = e; }
139
140 if (!this.hasNextPage()) {
141 if (callback) callback(this.error, null);
142 else if (this.error) throw this.error;
143 return null;
144 }
145
146 var params = AWS.util.copy(this.request.params);
147 if (!this.nextPageTokens) {
148 return callback ? callback(null, null) : null;
149 } else {
150 var inputTokens = config.inputToken;
151 if (typeof inputTokens === 'string') inputTokens = [inputTokens];
152 for (var i = 0; i < inputTokens.length; i++) {
153 params[inputTokens[i]] = this.nextPageTokens[i];
154 }
155 return service.makeRequest(this.request.operation, params, callback);
156 }
157 },
158
159 /**
160 * @return [Boolean] whether more pages of data can be returned by further
161 * requests
162 * @since v1.4.0
163 */
164 hasNextPage: function hasNextPage() {
165 this.cacheNextPageTokens();
166 if (this.nextPageTokens) return true;
167 if (this.nextPageTokens === undefined) return undefined;
168 else return false;
169 },
170
171 /**
172 * @api private
173 */
174 cacheNextPageTokens: function cacheNextPageTokens() {
175 if (Object.prototype.hasOwnProperty.call(this, 'nextPageTokens')) return this.nextPageTokens;
176 this.nextPageTokens = undefined;
177
178 var config = this.request.service.paginationConfig(this.request.operation);
179 if (!config) return this.nextPageTokens;
180
181 this.nextPageTokens = null;
182 if (config.moreResults) {
183 if (!jmespath.search(this.data, config.moreResults)) {
184 return this.nextPageTokens;
185 }
186 }
187
188 var exprs = config.outputToken;
189 if (typeof exprs === 'string') exprs = [exprs];
190 AWS.util.arrayEach.call(this, exprs, function (expr) {
191 var output = jmespath.search(this.data, expr);
192 if (output) {
193 this.nextPageTokens = this.nextPageTokens || [];
194 this.nextPageTokens.push(output);
195 }
196 });
197
198 return this.nextPageTokens;
199 }
200
201});