def __call__(self, environ, start_response): # Request for this state, modified by replace_start_response() # and used when an error is being reported. state = {} def replacement_start_response(status, headers, exc_info=None): """Overrides the default response to make errors parsable. """ try: status_code = int(status.split(' ')[0]) state['status_code'] = status_code except (ValueError, TypeError): # pragma: nocover raise Exception(( 'ErrorDocumentMiddleware received an invalid ' 'status %s' % status )) else: if (state['status_code'] / 100) not in (2, 3): # Remove some headers so we can replace them later # when we have the full error message and can # compute the length. headers = [(h, v) for (h, v) in headers if h not in ('Content-Length', 'Content-Type') ] # Save the headers in case we need to modify them. state['headers'] = headers return start_response(status, headers, exc_info) app_iter = self.app(environ, replacement_start_response) if (state['status_code'] / 100) not in (2, 3): req = webob.Request(environ) # Find the first TranslationHook in the array of hooks and use the # translatable_error object from it error = None for hook in self.app.hooks: if isinstance(hook, hooks.TranslationHook): error = hook.local_error.translatable_error break user_locale = self.best_match_language(req.accept_language) if (req.accept.best_match(['application/json', 'application/xml']) == 'application/xml'): try: # simple check xml is valid fault = etree.fromstring('\n'.join(app_iter)) # Add the translated error to the xml data if error is not None: for fault_string in fault.findall('faultstring'): fault_string.text = ( gettextutils.translate( error, user_locale)) body = ['<error_message>' + etree.tostring(fault) + '</error_message>'] except etree.XMLSyntaxError as err: LOG.error(_('Error parsing HTTP response: %s') % err) body = ['<error_message>%s' % state['status_code'] + '</error_message>'] state['headers'].append(('Content-Type', 'application/xml')) else: try: fault = json.loads('\n'.join(app_iter)) if error is not None and 'faultstring' in fault: fault['faultstring'] = ( gettextutils.translate( error, user_locale)) body = [json.dumps({'error_message': fault})] except ValueError as err: body = [json.dumps({'error_message': '\n'.join(app_iter)})] state['headers'].append(('Content-Type', 'application/json')) state['headers'].append(('Content-Length', str(len(body[0])))) else: body = app_iter return body
def __call__(self, environ, start_response): # Request for this state, modified by replace_start_response() # and used when an error is being reported. state = {} def replacement_start_response(status, headers, exc_info=None): """Overrides the default response to make errors parsable. """ try: status_code = int(status.split(' ')[0]) state['status_code'] = status_code except (ValueError, TypeError): # pragma: nocover raise Exception(('ErrorDocumentMiddleware received an invalid ' 'status %s' % status)) else: if (state['status_code'] / 100) not in (2, 3): # Remove some headers so we can replace them later # when we have the full error message and can # compute the length. headers = [(h, v) for (h, v) in headers if h not in ('Content-Length', 'Content-Type')] # Save the headers in case we need to modify them. state['headers'] = headers return start_response(status, headers, exc_info) app_iter = self.app(environ, replacement_start_response) if (state['status_code'] / 100) not in (2, 3): req = webob.Request(environ) # Find the first TranslationHook in the array of hooks and use the # translatable_error object from it error = None for hook in self.app.hooks: if isinstance(hook, hooks.TranslationHook): error = hook.local_error.translatable_error break user_locale = self.best_match_language(req.accept_language) if (req.accept.best_match(['application/json', 'application/xml' ]) == 'application/xml'): try: # simple check xml is valid fault = etree.fromstring('\n'.join(app_iter)) # Add the translated error to the xml data if error is not None: for fault_string in fault.findall('faultstring'): fault_string.text = (gettextutils.translate( error, user_locale)) body = [ '<error_message>' + etree.tostring(fault) + '</error_message>' ] except etree.XMLSyntaxError as err: LOG.error(_('Error parsing HTTP response: %s') % err) body = [ '<error_message>%s' % state['status_code'] + '</error_message>' ] state['headers'].append(('Content-Type', 'application/xml')) else: try: fault = json.loads('\n'.join(app_iter)) if error is not None and 'faultstring' in fault: fault['faultstring'] = (gettextutils.translate( error, user_locale)) body = [json.dumps({'error_message': fault})] except ValueError as err: body = [json.dumps({'error_message': '\n'.join(app_iter)})] state['headers'].append(('Content-Type', 'application/json')) state['headers'].append(('Content-Length', str(len(body[0])))) else: body = app_iter return body