@@ -133,18 +133,27 @@ class Batch(Connection):
133133
134134 :type client: :class:`google.cloud.storage.client.Client`
135135 :param client: The client to use for making connections.
136+
137+ :type raise_exception: bool
138+ :param raise_exception:
139+ (Optional) Defaults to True. If True, instead of adding exceptions
140+ to the list of return responses, the final exception will be raised.
141+ Note that exceptions are unwrapped after all operations are complete
142+ in success or failure, and only the last exception is raised.
136143 """
137144
138145 _MAX_BATCH_SIZE = 1000
139146
140- def __init__ (self , client ):
147+ def __init__ (self , client , raise_exception = True ):
141148 api_endpoint = client ._connection .API_BASE_URL
142149 client_info = client ._connection ._client_info
143150 super (Batch , self ).__init__ (
144151 client , client_info = client_info , api_endpoint = api_endpoint
145152 )
146153 self ._requests = []
147154 self ._target_objects = []
155+ self ._responses = []
156+ self ._raise_exception = raise_exception
148157
149158 def _do_request (
150159 self , method , url , headers , data , target_object , timeout = _DEFAULT_TIMEOUT
@@ -219,24 +228,34 @@ def _prepare_batch_request(self):
219228 _ , body = payload .split ("\n \n " , 1 )
220229 return dict (multi ._headers ), body , timeout
221230
222- def _finish_futures (self , responses ):
231+ def _finish_futures (self , responses , raise_exception = True ):
223232 """Apply all the batch responses to the futures created.
224233
225234 :type responses: list of (headers, payload) tuples.
226235 :param responses: List of headers and payloads from each response in
227236 the batch.
228237
238+ :type raise_exception: bool
239+ :param raise_exception:
240+ (Optional) Defaults to True. If True, instead of adding exceptions
241+ to the list of return responses, the final exception will be raised.
242+ Note that exceptions are unwrapped after all operations are complete
243+ in success or failure, and only the last exception is raised.
244+
229245 :raises: :class:`ValueError` if no requests have been deferred.
230246 """
231247 # If a bad status occurs, we track it, but don't raise an exception
232248 # until all futures have been populated.
249+ # If raise_exception=False, we add exceptions to the list of responses.
233250 exception_args = None
234251
235252 if len (self ._target_objects ) != len (responses ): # pragma: NO COVER
236253 raise ValueError ("Expected a response for every request." )
237254
238255 for target_object , subresponse in zip (self ._target_objects , responses ):
239- if not 200 <= subresponse .status_code < 300 :
256+ # For backwards compatibility, only the final exception will be raised.
257+ # Set raise_exception=False to include all exceptions to the list of return responses.
258+ if not 200 <= subresponse .status_code < 300 and raise_exception :
240259 exception_args = exception_args or subresponse
241260 elif target_object is not None :
242261 try :
@@ -247,9 +266,16 @@ def _finish_futures(self, responses):
247266 if exception_args is not None :
248267 raise exceptions .from_http_response (exception_args )
249268
250- def finish (self ):
269+ def finish (self , raise_exception = True ):
251270 """Submit a single `multipart/mixed` request with deferred requests.
252271
272+ :type raise_exception: bool
273+ :param raise_exception:
274+ (Optional) Defaults to True. If True, instead of adding exceptions
275+ to the list of return responses, the final exception will be raised.
276+ Note that exceptions are unwrapped after all operations are complete
277+ in success or failure, and only the last exception is raised.
278+
253279 :rtype: list of tuples
254280 :returns: one ``(headers, payload)`` tuple per deferred request.
255281 """
@@ -269,7 +295,8 @@ def finish(self):
269295 raise exceptions .from_http_response (response )
270296
271297 responses = list (_unpack_batch_response (response ))
272- self ._finish_futures (responses )
298+ self ._finish_futures (responses , raise_exception = raise_exception )
299+ self ._responses = responses
273300 return responses
274301
275302 def current (self ):
@@ -283,7 +310,7 @@ def __enter__(self):
283310 def __exit__ (self , exc_type , exc_val , exc_tb ):
284311 try :
285312 if exc_type is None :
286- self .finish ()
313+ self .finish (raise_exception = self . _raise_exception )
287314 finally :
288315 self ._client ._pop_batch ()
289316
0 commit comments