def test_set_rollback_for_transaction_in_managed_mode(self): class MockTransaction(object): called_rollback = False called_leave_transaction_management = False def is_managed(self): return True def is_dirty(self): return True def rollback(self): self.called_rollback = True def leave_transaction_management(self): self.called_leave_transaction_management = True dirty_mock_transaction = MockTransaction() compat.transaction = dirty_mock_transaction compat.set_rollback() assert dirty_mock_transaction.called_rollback is True assert dirty_mock_transaction.called_leave_transaction_management is True clean_mock_transaction = MockTransaction() clean_mock_transaction.is_dirty = lambda: False compat.transaction = clean_mock_transaction compat.set_rollback() assert clean_mock_transaction.called_rollback is False assert clean_mock_transaction.called_leave_transaction_management is True
def datal_exception_handler(exception, context): # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exception, context) # Now add the HTTP status code to the response. if not response is None: response.data['status'] = response.status_code if not 'description' in response.data: response.data['description'] = '' if 'detail' in response.data: response.data['description'] = response.data.pop('detail') response.data['error'] = str(exception.__class__.__name__) response.data['type'] = 'api-error' elif isinstance(exception, DATALException): set_rollback() response = Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) response.data['status'] = exception.status_code response.data['description'] = exception.description % {} response.data['error'] = str(exception.__class__.__name__) response.data['type'] = exception.tipo elif not settings.DEBUG: logger = logging.getLogger(__name__) trace = '\n'.join(traceback.format_exception(*(sys.exc_info()))) logger.error('[UnexpectedCatchError] %s. %s %s' % (str(exception), repr(exception), trace)) set_rollback() response = Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) response.data['status'] = response.status_code response.data['description'] = json.dumps(str(exception)) response.data['error'] = str(exception.__class__.__name__) response.data['type'] = 'unexpected-error' return response
def datal_exception_handler(exception, context): # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exception, context) # Now add the HTTP status code to the response. if response is not None: response.data['status'] = response.status_code if not 'description' in response.data: response.data['description'] = '' if 'detail' in response.data: response.data['description'] = response.data.pop('detail') response.data['error'] = str(exception.__class__.__name__) response.data['type'] = 'api-error' elif isinstance(exception, DATALException): set_rollback() response = Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) response.data['status'] = exception.status_code response.data['description'] = exception.description % {} response.data['error'] = str(exception.__class__.__name__) response.data['type'] = exception.tipo elif not settings.DEBUG: logger = logging.getLogger(__name__) trace = '\n'.join(traceback.format_exception(*(sys.exc_info()))) logger.error('[UnexpectedCatchError] %s. %s %s' % ( str(exception), repr(exception), trace)) set_rollback() response = Response({}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) response.data['status'] = response.status_code response.data['description'] = str(exception) response.data['error'] = str(exception.__class__.__name__) response.data['type'] = 'unexpected-error' return response
def custom_exception_handler(exc, context): response = rest_exception_handler(exc, context) if isinstance(exc, DjangoValidationError): data = {'detail': exc.messages} set_rollback() return Response(data, status=status.HTTP_400_BAD_REQUEST) return response
def custom_handler(exc, context): """ Handle exceptions that are NOT `rest_framework.exceptions.APIException`-based exceptions """ # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exc, context) request = context.get('request', None) view = context.get('view', None) if not response: q('CUSTOM EXCEPTION!', exc, request.data) # Get exception info exc_type, exc_value, exc_trace = sys.exc_info() q(exc_type, exc_value, exc_trace) # Customize exceptions that translate to HTTP-4XX status-codes if isinstance(exc, core_exceptions.ObjectDoesNotExist): msg = str(exc) # TODO! Translate this! data = {'detail': six.text_type(msg)} status_code = status.HTTP_404_NOT_FOUND elif isinstance(exc, AssertionError): if isinstance(exc.message, basestring): data = {'detail': six.text_type(exc.message)} else: data = exc.message status_code = status.HTTP_400_BAD_REQUEST else: q('UNHANDLED CUSTOM EXCEPTION!') # Unhandled exception; print and then just wrap to make render properly traceback.print_exception(exc_type, exc_value, exc_trace) try: msg = str(exc) # TODO! Translate this! # http://stackoverflow.com/a/696095/1008905 raise WrappedException, (msg, exc_type, exc_value), exc_trace except Exception, exc: response = exception_handler(exc, context) return response # Add some additional information to the response-data if view: data['view'] = view.__class__.__name__ if context.get('kwargs', None): data['kwargs'] = context['kwargs'] if request.data: data['request'] = request.data if not status_code: status_code = exc.status_code if exc.status_code else 500 set_rollback() return Response(data, status=status_code)
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait detail = exc.detail field_name = '' while isinstance(detail, dict): field_name = next(iter(detail.keys())) detail = detail[field_name] if isinstance(detail, list): detail = detail[0] err_data = { 'code': exc.code if hasattr(exc, 'code') else exc.status_code, 'msg': exc.msg if hasattr(exc, 'msg') else detail, 'field_name': field_name } set_rollback() return Response(err_data, status=200, headers=headers) elif isinstance(exc, Http404): set_rollback() err_data = {'code': 404, 'msg': exc.__repr__()} return Response(err_data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): err_data = {'code': 403, 'msg': exc.__repr__()} set_rollback() return Response(err_data, status=status.HTTP_403_FORBIDDEN) elif isinstance(exc, DatabaseError): logger.error(exc) set_rollback() # 数据库异常 err_data = {'code': 500, 'msg': exc.__repr__()} response = Response(err_data, status=status.HTTP_507_INSUFFICIENT_STORAGE) return response elif isinstance(exc, RedisError): set_rollback() # 数据库异常 err_data = {'code': 500, 'msg': exc.__repr__()} response = Response(err_data, status=status.HTTP_507_INSUFFICIENT_STORAGE) return response
def custom_exception_handler(exc, context): if isinstance(exc, (NotAuthenticated, AuthenticationFailed)): data = { "code": error_codes.Unauthorized.code, "data": {"login_url": {"full": settings.LOGIN_FULL, "simple": settings.LOGIN_SIMPLE}}, "message": error_codes.Unauthorized.message, "request_id": local.request_id, } return Response(data, status=error_codes.Unauthorized.status_code) elif isinstance(exc, (ValidationError, ParseError)): detail = exc.detail if "non_field_errors" in exc.detail: message = detail["non_field_errors"] else: message = detail data = {"code": 400, "message": message, "data": None, "request_id": local.request_id} set_rollback() return Response(data, status=200, headers={}) elif isinstance(exc, APIError): # 更改返回的状态为为自定义错误类型的状态码 data = {"code": exc.code, "message": exc.message, "data": None, "request_id": local.request_id} set_rollback() return Response(data) elif isinstance(exc, (MethodNotAllowed, PermissionDenied)): data = {"code": 400, "message": exc.detail, "data": None, "request_id": local.request_id} set_rollback() return Response(data, status=200) elif isinstance(exc, Http404): data = {"code": 404, "message": _("资源未找到"), "data": None} set_rollback() return Response(data, status=200) elif isinstance(exc, backend_exceptions.APIError): data = {"code": exc.code, "message": "%s" % exc, "data": exc.data, "request_id": local.request_id} set_rollback() return Response(data, status=exc.status_code) # Call REST framework's default exception handler to get the standard error response. response = exception_handler(exc, context) # Use a default error code if response is not None: response.data.update(code="ERROR") # catch all exception, if in prod/stag mode if settings.IS_COMMON_EXCEPTION_MSG and not settings.DEBUG and not response: logger.exception("restful api unhandle exception") data = { "code": 500, "message": _("数据请求失败,请稍后再试{}").format(settings.COMMON_EXCEPTION_MSG), "data": None, "request_id": local.request_id, } return Response(data) return response
def exception_response(data, status_code, headers, django=False): if django: res = JsonResponse(data, status=status_code) set_django_response_headers(res, headers) else: res = Response(data, status=status_code, headers=headers) res.is_final = True set_rollback() return res
def exception_handler(exc, content): data = { 'result': False, 'data': None } if isinstance(exc, (NotAuthenticated, AuthenticationFailed)): data = { 'result': False, 'code': ResponseCodeStatus.UNAUTHORIZED, 'detail': u'用户未登录或登录态失效,请使用登录链接重新登录', 'login_url': '' } return Response(data, status=status.HTTP_403_FORBIDDEN) if isinstance(exc, PermissionDenied) or isinstance(exc, RestPermissionDenied): message = exc.detail if hasattr(exc, 'detail') else u'该用户没有该权限功能' data = { 'result': False, 'code': ResponseCodeStatus.PERMISSION_DENIED, 'message': message } return Response(data, status=status.HTTP_403_FORBIDDEN) else: if isinstance(exc, ValidationError): data.update({ 'code': ResponseCodeStatus.VALIDATE_ERROR, 'message': exc.detail }) elif isinstance(exc, MethodNotAllowed): data.update({ 'code': ResponseCodeStatus.METHOD_NOT_ALLOWED, 'message': exc.detail, }) elif isinstance(exc, Http404): # 更改返回的状态为为自定义错误类型的状态码 data.update({ 'code': ResponseCodeStatus.OBJECT_NOT_EXIST, 'message': exc.message, }) else: # 调试模式 logger.error(traceback.format_exc()) print traceback.format_exc() # if settings.RUN_MODE != 'PRODUCT': # raise exc # 正式环境,屏蔽500 data.update({ 'code': ResponseCodeStatus.SERVER_500_ERROR, 'message': exc.message, }) set_rollback() return Response(data, status=status.HTTP_200_OK)
def YB_exception_handler(exc, context): """ Funcion de tratamiento de error en peticiones por defecto El contecto incluye los siguientes: 'view': self, 'args': getattr(self, 'args', ()), 'kwargs': getattr(self, 'kwargs', {}), 'request': getattr(self, 'request', None) """ try: milog.info("Excepcion capturada de alto nivel: %s",exc.__str__()) if settings.DEBUG: milog.exception(exc) except: pass """ Se capturaran todas y se devolvera un mensaje 400 si no mas especifico El mensaje de vuelta tendra la estructura: tipo: 1-Error Arquitectura/API REST 2-Error de aplicacion 3-Validacion 4-Error excepcion capturada msg: Mensaje por defecto data:Otros datos relevantes """ miresp={} code=status.HTTP_400_BAD_REQUEST #tratamiento de errores de validacion if isinstance(exc,ValidationError): miresp['tipo']=3 miresp['msg']=[_('Error en los datos recibidos. Revise mensajes adicionales.')] miresp['data']=exc.detail else: #Comportamiento por defecto response = exception_handler(exc, context) if not(response is None): #Pasamos a nuestro estandar miresp['tipo']=1 miresp['msg']=[response.data.get('detail',None)] response.data=miresp return response else: #Tratamiento de excepciones propias y no controladas por API if isinstance(exc,excepcionAplicacion): if isinstance(exc,excepcionAplicacionRollBack): set_rollback() miresp['tipo']=2 miresp['msg']=[force_text(exc.__str__())] else: set_rollback() miresp['tipo']=4 miresp['msg']=[force_text(exc.__str__())] return Response(data=miresp,status=code)
def my_exception_handler(exc, context): if ( isinstance(exc, exceptions.APIException) and isinstance(exc.detail, (list, dict)) ): detail = " - ".join( ["{}: {}".format(k, v[0]) for k, v in exc.detail.items()]) response = {"error": detail} set_rollback() return Response(response, status=exc.status_code) else: exception_handler(exc, context)
def custom_exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exc, context) # No response means DRF couldn't handle it # Output a generic 500 in a JSON format if response is None: logging.exception('Uncaught Exception', exc_info=exc) set_rollback() return Response({'detail': 'Server Error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return response
def get_exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, dict): if exc.detail.get('card'): data = {'detail': '卡号已存在'} else: data = [v[0] for k, v in exc.detail.items()] data = {'detail': ','.join(data)} print data elif isinstance(exc.detail, list): data = {'detail': ''.join(exc.detail)} else: data = {'detail': exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) # elif isinstance(exc, Http404): # msg = _('Not found.') # data = {'msgs': six.text_type(msg)} # # set_rollback() # return Response(data, status=status.HTTP_404_NOT_FOUND) # elif isinstance(exc, PermissionDenied): # msg = _('Permission denied.') # data = {'msgs': six.text_type(msg)} # # set_rollback() # return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): if isinstance(exc, exceptions.ValidationError): set_rollback() return error(exc.status_code, exc.detail) elif isinstance(exc, Http404): msg = 'Not found.' set_rollback() return error(404, msg) elif isinstance(exc, PermissionDenied): msg = 'Permission denied.' set_rollback() return error(403, msg) elif isinstance(exc, exceptions.APIException): set_rollback() return error(exc.status_code, exc.detail) request = context.get('request') logger.error('Internal Server Error: %s', request.path, exc_info=sys.exc_info(), extra={ 'status_code': 500, 'request': request } ) return error(500, exc.message)
def custom_exception_handler(exc, context): """Handle select errors not handled by DRF's default exception handler.""" response = exception_handler(exc, context) if response is None: if isinstance(exc, ProtectedError): # provides handling of ProtectError from use of models # ForeignKey on_delete=PROTECT argument. msg = _('Cannot delete protected objects while ' 'related objects still exist') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_400_BAD_REQUEST) return response
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ request = context.get('request') view_class = context.get('view').__class__.__name__ if not isinstance(exc, NotAuthenticated) and not view_class == "ImageViewSet": logger.exception(exc, extra={'request': request}) if isinstance(exc, APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait # TODO: Investigate if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'error': True, 'detail': exc.detail, 'error_code': exc.default_code} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'error': True, 'detail': six.text_type(msg), 'error_code': 'not_found'} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, ObjectDoesNotExist): msg = _('Object Not found.') data = {'error': True, 'detail': six.text_type(msg), 'error_code': 'not_found'} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'error': True, 'detail': six.text_type(msg), 'error_code': 'permission_denied'} message = six.text_type(exc) if message: data['detail'] = message set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def custom_rest_exception_handler(exc, context): """ Custom rest api exception handler """ from rest_framework import exceptions from rest_framework.compat import set_rollback from rest_framework.views import exception_handler response = exception_handler(exc, context) if isinstance(exc, IntegrityError) and ('already exists' in str(exc) or 'must make a unique set' in str(exc)): data = {'detail': 'duplicate unique key'} set_rollback() return Response(data, status=status.HTTP_409_CONFLICT) if isinstance(exc, exceptions.NotAuthenticated): response.status_code = status.HTTP_401_UNAUTHORIZED if isinstance(exc, exceptions.ValidationError) and ( 'already exists' in str(exc) or 'must make a unique set' in str(exc)): response.status_code = status.HTTP_409_CONFLICT return response
def custom_exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. response = exception_handler(exc, context) # No response means DRF couldn't handle it # Output a generic 500 in a JSON format if response is None: logging.exception('Uncaught Exception', exc_info=exc) set_rollback() return Response({'detail': 'Server Error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # log a few different types of exception instead of use APIException if isinstance(exc, (DeisException, ServiceUnavailable, HealthcheckException)): logging.exception(exc.__cause__, exc_info=exc) return response
def G3WExceptionHandler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ data = G3WAPIResults() data.result = False if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc, exceptions.ValidationError): data.error = { 'code': 'validation', 'message': _('Data are not correct or insufficent!') } else: data.error = { 'code': 'servererror', 'message': _('A error server is occured!') } data.results['error']['data'] = exc.detail set_rollback() return Response(data.results, status=exc.status_code, headers=headers) set_rollback() return Response(data.results, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found') data.error = six.text_type(msg) set_rollback() return Response(data.results, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied') data.error = six.text_type(msg) set_rollback() return Response(data.results, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ request = context.get('request') logger.exception(exc, extra={'request': request}) if isinstance(exc, APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait # TODO: Investigate if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'error': True, 'detail': exc.detail, 'error_code': exc.default_code} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'error': True, 'detail': six.text_type(msg), 'error_code': 'not_found'} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, ObjectDoesNotExist): msg = _('Object Not found.') data = {'error': True, 'detail': six.text_type(msg), 'error_code': 'not_found'} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'error': True, 'detail': six.text_type(msg), 'error_code': 'permission_denied'} message = six.text_type(exc) if message: data['detail'] = message set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ request_url = context['request'].build_absolute_uri() if isinstance(exc, APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = { 'msg': exc.detail, 'code': exc.code, 'error_code': exc.error_code, 'request_url': request_url } set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = { 'msg': six.text_type(msg), 'error_code': 40000, 'request_url': request_url } set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND)
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. Adds support the DRF default to also handle django.core.exceptions.ValidationError Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ response = original_exception_handler(exc, context) if response: return response elif isinstance(exc, DjangoValidationError): data = {'messages': exc.messages} set_rollback() return Response(data, status=status.HTTP_400_BAD_REQUEST) return None
def custom_rest_exception_handler(exc, context): ''' Custom rest api exception handler ''' from rest_framework import exceptions from rest_framework.compat import set_rollback from rest_framework.views import exception_handler response = exception_handler(exc, context) if isinstance( exc, IntegrityError) and ('already exists' in str(exc) or 'must make a unique set' in str(exc)): data = {'detail': 'duplicate unique key'} set_rollback() return Response(data, status=status.HTTP_409_CONFLICT) if isinstance(exc, exceptions.NotAuthenticated): response.status_code = status.HTTP_401_UNAUTHORIZED if isinstance(exc, exceptions.ValidationError) and ( 'already exists' in str(exc) or 'must make a unique set' in str(exc)): response.status_code = status.HTTP_409_CONFLICT return response
def full_exception_handler(exc, context): """ Transform dict-like error-messages to flat list. """ if isinstance(exc, exceptions.APIException): set_rollback() data = exc.get_full_details() errors = data if isinstance(exc.detail, dict): errors = [] for field_name, values in data.items(): for value in values.copy(): if field_name != 'non_field_errors': value['field'] = field_name errors.append(value) return Response(errors, status=exc.status_code) return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait errors = exc.detail if isinstance(exc.detail, list): error_detail = exc.detail[0] elif isinstance(exc.detail, dict): # TODO 处理嵌套字典的错误,嵌套serializer中会出现此种情况,对于嵌套的报错,使用最里层的那个报错字符串 error_detail = exc.detail.copy().popitem()[1][0] set_rollback() else: error_detail = exc.detail errors = None error_code = getattr(error_detail, 'code', 'invalid') if isinstance(error_code, six.text_type): error_code = 1001 set_rollback() if error_code < 1000: # drf内部错误有时通过error_detail中获取的code和实际http应该返回的code不一致,所以如果不是验证错误 # 使用exc的status_code作为返回码 error_code = exc.status_code return {'code': error_code, 'detail': error_detail, 'errors': errors} return {'code': -1, 'detail': 'unknown'}
def custom_exception_handler(exc, context): # give more context on the error since DRF masks it as Not Found if isinstance(exc, Http404): set_rollback() return Response(str(exc), status=status.HTTP_404_NOT_FOUND) # Call REST framework's default exception handler after specific 404 handling, # to get the standard error response. response = exception_handler(exc, context) # No response means DRF couldn't handle it # Output a generic 500 in a JSON format if response is None: logging.exception('Uncaught Exception', exc_info=exc) set_rollback() return Response({'detail': 'Server Error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # log a few different types of exception instead of using APIException if isinstance(exc, (DeisException, ServiceUnavailable, HealthcheckException)): logging.exception(exc.__cause__, exc_info=exc) return response
def custom_exception_handler(exc, context): if isinstance(exc, Error): set_rollback() logger.error(exc) return ErrorResponse(exc.err_code, exc.err_result, exc.message, status=exc.status_code) if isinstance(exc, KeyError): data = 'key error.' set_rollback() logger.error(exc) return ErrorResponse(2001, data, u'KeyError', status=status.HTTP_200_OK) if isinstance(exc, ParseError): data = exc.detail set_rollback() logger.error(exc) return ErrorResponse(2001, data, u'parse error', status=status.HTTP_200_OK) if isinstance(exc, ValidationError): data = exc.detail if data.has_key('email_title'): return ErrorResponse(2104, data, u'email_title can not be null', status=status.HTTP_200_OK) set_rollback() logger.error(exc) return ErrorResponse(2001, data, u'validation error', status=status.HTTP_200_OK) if isinstance(exc, IntegrityError): data = str(exc) return ErrorResponse(3101, data, u'duplicate error', status=status.HTTP_200_OK)
def custom_exception_handler(exc, context): """ Custom django rest framework exception handler that includes 'status_code' field in the responses. """ # Call REST framework's default exception handler first response = exception_handler(exc, context) # Catch unexpected exceptions if response is None: if isinstance(exc, Exception): print('\n\nUnhandled Exception\n') print(exc) print('\n') data = {'detail': 'A server error occurred.'} set_rollback() response = Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # Now add the HTTP status code to the response. if response is not None: response.data['status_code'] = response.status_code return response
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, "auth_header", None): headers["WWW-Authenticate"] = exc.auth_header if getattr(exc, "wait", None): headers["Retry-After"] = "%d" % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {"detail": exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _("Not found.") data = {"detail": six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _("Permission denied.") data = {"detail": six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) elif isinstance(exc, DjangoValidationError): msg = _("Validation error.") data = {"detail": exc.messages} set_rollback() return Response(data, status=status.HTTP_400_BAD_REQUEST) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ print(exc) if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: # data = {'detail': exc.detail} data = exc.detail code = -100 if isinstance(exc,AuthenticationFailed): code = 401 set_rollback() return DefaultJsonResponse(message=data,code=code, status=200, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'detail': six.text_type(msg)} set_rollback() return DefaultJsonResponse(message=data, code=-100,status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'detail': six.text_type(msg)} set_rollback() return DefaultJsonResponse(message=msg, status=status.HTTP_403_FORBIDDEN) elif isinstance(exc,ConditionDenied): print(exc.detail) if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'detail': exc.detail} print(type(exc)) print(data) return DefaultJsonResponse(message=data.get('detail'), code=exc.code, status=status.HTTP_200_OK,) elif isinstance(exc,PageInvalidate): # 客户端请求的页码超出 return DefaultJsonResponse(message=exc.detail, code=exc.code, status=status.HTTP_200_OK,) elif isinstance(exc,VertifySmsNotMatchException): return DefaultJsonResponse(message=exc.detail, code= appcodes.SMS_VERIFY_FAILED, status=status.HTTP_200_OK,) elif isinstance(exc,AdminDenied): return DefaultJsonResponse(message='MDZZ') return None
def exception_handler(exc, context): # Custom Error if isinstance(exc, APIError): set_rollback() return APIResponse(code=exc.err_code, message=exc.message, data=None) # Authentication if isinstance(exc, exceptions.AuthenticationFailed): return APIResponse(code=errors.TOKEN_EXPIRED, message=exc.default_detail, data={'detail': exc.detail}, status_code=exc.status_code) # Throttled if isinstance(exc, exceptions.Throttled): return APIResponse(code=errors.THROTTLE_REACHED, message=exc.default_detail, data={'detail': exc.detail}) # Common if isinstance(exc, exceptions.APIException): # print(exc) return APIResponse(code=errors.OTHER_ERROR, message=exc.default_detail, data={'detail': exc.detail})
def exception_handler(exc, context): if isinstance(exc, exceptions.ValidationError): errors = [] message = "Validation failed." for field, field_errors in exc.detail.items(): if field == "non_field_errors": field = None for error in field_errors: if isinstance(error, ValidationErrorDetail): message = error.message error = {"error": error.error} else: error = {"error": error} if field: error["field"] = field errors.append(error) data = {"message": message, "errors": errors} return Response(data, status=422) if isinstance(exc, exceptions.APIException): if isinstance(exc.detail, list): errors = [{"error": e} for e in exc.detail] data = {"message": "API exception occurred.", "errors": errors} elif isinstance(exc.detail, dict): message = exc.detail.get("message", "API exception occurred.") errors = [{"error": e} for e in exc.detail.get("errors", [])] data = {'message': message, "errors": errors} else: data = {'message': exc.detail, "errors": []} set_rollback() return Response(data, status=exc.status_code) elif isinstance(exc, Http404): data = {"message": "Not found.", "errors": [{"error": "not_found"}]} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): data = { "message": "Permision denied.", "errors": [{ "error": "permission_denied" }] } set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): if isinstance(exc, exceptions.APIException): set_rollback() return error(exc.status_code, exc.detail) elif isinstance(exc, Http404): msg = 'Not found.' set_rollback() return error(404, msg) elif isinstance(exc, PermissionDenied): msg = 'Permission denied.' set_rollback() return error(403, msg) return error(500, exc.message)
def exception_handler(exc, context): """ Logging exceptions. """ request = context.get('request') if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (dict)): data = exc.detail elif isinstance(exc.detail, (list)): data = {'detail': ', '.join(exc.detail)} else: data = {'detail': exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'detail': six.text_type(msg)} set_rollback() logger.exception( "----------- API Exception 404: User: {}, data: {}, source: {}, full_path: {}" .format(request.user, request._full_data, request.META.get('HTTP_SOURCE'), request.get_full_path())) return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. logger.exception( "----------- API Exception: User: {}, data: {}, source: {}, full_path: {}" .format(request.user, request._full_data, request.META.get('HTTP_SOURCE'), request.get_full_path())) return None
def custom_exception_handler(exc, context): # Call REST framework's default exception handler first, # to get the standard error response. custom_error = CustomError() if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): if exc.detail is list: for errors in exc.detail: for key, item in errors.items(): custom_error.add(key, item) else: for key, item in exc.detail.items(): custom_error.add(key, item) else: custom_error.add(Common.REST_FRAMEWORK['NON_FIELD_ERRORS_KEY'], [exc.detail]) set_rollback() return Response(custom_error.get(), status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = 'Не найден' custom_error.add(Common.REST_FRAMEWORK['NON_FIELD_ERRORS_KEY'], [six.text_type(msg)]) set_rollback() return Response(custom_error.get(), status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = 'Доступ запрещен' custom_error.add(Common.REST_FRAMEWORK['NON_FIELD_ERRORS_KEY'], [six.text_type(msg)]) set_rollback() return Response(custom_error.get(), status=status.HTTP_403_FORBIDDEN) return custom_error.get()
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['X-Throttle-Wait-Seconds'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: class_name = exc.__class__.__name__ class_module = exc.__class__.__module__ data = { "_error_message": force_text(exc.detail), "_error_type": "{0}.{1}".format(class_module, class_name) } print(data) set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'_error_message': six.text_type(msg)} set_rollback() print(data) return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'_error_message': six.text_type(msg)} set_rollback() print(data) return Response(data, status=status.HTTP_403_FORBIDDEN) return None
def simple_exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. Return 400 errors like this: [ {"field":"non_field_errors", "message":"User with this email already exist."}, {"field":"field1", "message":"Someone other error."}, ] """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait data = convert_to_list(exc.detail, api_settings.NON_FIELD_ERRORS_KEY) set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {'detail': exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'detail': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # throw django's error page if debug is True if settings.DEBUG: exception_reporter = debug.ExceptionReporter(context.get('request'), *sys.exc_info()) return HttpResponse(exception_reporter.get_traceback_html(), status=500) return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ headers = None if isinstance(exc, APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait message_code = exc.detail status_code = exc.status_code set_rollback() elif isinstance(exc, Http404): msg = _('Not found.') message_code = six.text_type(msg) status_code = status.HTTP_404_NOT_FOUND set_rollback() elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') message_code = six.text_type(msg) status_code = status.HTTP_403_FORBIDDEN set_rollback() else: message_code = str(exc) status_code = status.HTTP_500_INTERNAL_SERVER_ERROR return harri_response({}, message_code=message_code, status_code=status_code, headers=headers)
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ exception_detail_key = api_settings.EXCEPTION_DETAIL_KEY if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {exception_detail_key: exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {exception_detail_key: six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {exception_detail_key: six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ error_key = api_settings.EXCEPTION_HANDLER_ERROR_KEY if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): data = exc.detail else: data = {error_key: exc.detail} set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {error_key: six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {error_key: six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) return None
def pingo_exception_handler(exc, context): if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait data = {} if isinstance(exc.detail, list): data['detail'] = { 'error': exc.detail, } if isinstance(exc.detail, dict): data['detail'] = exc.detail if isinstance(exc, ScheduleConflictionError): data['title'] = _('Schedule Confliction') data['message'] = _('The schedule you want to set is conflicted to existed schedules.') elif isinstance(exc, exceptions.AuthenticationFailed): data['title'] = _('Authentication Failed') data['message'] = exc.detail elif isinstance(exc, exceptions.NotAuthenticated): data['title'] = _('Not Authenticated') data['message'] = _('User credential is required to perform this action.') elif isinstance(exc, exceptions.PermissionDenied): data['title'] = _('Permission Denied') data['message'] = exc.detail elif isinstance(exc, exceptions.ValidationError): data['title'] = _('Validation Failed') data['message'] = _('Provided data is failed to pass the validation.') else: data['title'] = _('Error') data['message'] = _('Unknown error.') set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = { 'title': _('Not Found'), 'message': _('Requested resource is not found.'), } set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = { 'title': _('Permission Denied'), 'message': _('You have no permission to do so.'), } set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) if settings.DEBUG: return None # return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def custom_exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ if isinstance(exc, exceptions.APIException): headers = {} if getattr(exc, 'auth_header', None): headers['WWW-Authenticate'] = exc.auth_header if getattr(exc, 'wait', None): headers['Retry-After'] = '%d' % exc.wait if isinstance(exc.detail, (list, dict)): # Concatenate all field and non_field errors for message: message = '' for key in exc.detail: try: if isinstance(exc.detail[key], str): message += exc.detail[key] + ' ' else: for error in exc.detail[key]: # Don't include duplicates in universal error message if error not in message: message += error + ' ' except TypeError: if key == 'non_field_errors': message = exc.detail[key][0] else: message = _('Invalid request.') if message.endswith(' '): message = message[:-1] # remove last space data = OrderedDict([('status', 'error'), ('message', message), ('data', exc.detail)]) else: data = OrderedDict([('status', 'error'), ('message', exc.detail)]) set_rollback() return Response(data, status=exc.status_code, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'status': 'error', 'message': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'status': 'error', 'message': six.text_type(msg)} set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None
def exception_handler(exc, context): if isinstance(exc, exceptions.ValidationError): errors = [] message = "Validation failed." for field, field_errors in exc.detail.items(): if field == "non_field_errors": field = None for error in field_errors: if isinstance(error, ValidationErrorDetail): message = error.message error = {"error": error.error} else: error = {"error": error} if field: error["field"] = field errors.append(error) data = { "message": message, "errors": errors } return Response(data, status=422) if isinstance(exc, exceptions.APIException): if isinstance(exc.detail, list): errors = [{"error": e} for e in exc.detail] data = {"message": "API exception occurred.", "errors": errors} elif isinstance(exc.detail, dict): message = exc.detail.get("message", "API exception occurred.") errors = [{"error": e} for e in exc.detail.get("errors", [])] data = {'message': message, "errors": errors} else: data = {'message': exc.detail, "errors":[]} set_rollback() return Response(data, status=exc.status_code) elif isinstance(exc, Http404): data = { "message":"Not found.", "errors":[ {"error":"not_found"} ] } set_rollback() return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): data = { "message":"Permision denied.", "errors":[ {"error":"permission_denied"} ] } set_rollback() return Response(data, status=status.HTTP_403_FORBIDDEN) # Note: Unhandled exceptions will raise a 500 error. return None