Django REST 異常處理詳解
異常
異常處理…允許錯(cuò)誤處理在程序結(jié)構(gòu)的中心或者高層級的地方被清晰有條理的組織起來。
Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.— Doug Hellmann, Python Exception Handling Techniques
Rest框架視圖中的異常處理
Exception handling in REST framework views
REST框架的視圖處理了各種異常,并正確地返回了錯(cuò)誤響應(yīng)。
REST framework’s views handle various exceptions, and deal with returning appropriate error responses.
被處理的異常有:
Rest框架內(nèi)部拋出的APIException的子類。
Django的Http404異常。
Django的PermissionDenied異常
針對每種情況,REST框架將返回一個(gè)包含了正確的狀態(tài)碼和content-type的響應(yīng)。響應(yīng)體包含了任何關(guān)于錯(cuò)誤本身的額外細(xì)節(jié)。
大部分的錯(cuò)誤響應(yīng)將在響應(yīng)體中包含了一個(gè)detail的鍵。
例如下面請求:
DELETE http://api.example.com/foo/bar HTTP/1.1
Accept: application/json
你還可能接收到一個(gè)錯(cuò)誤響應(yīng),表明對該資源DELETE方法不允許的。
HTTP/1.1 405 Method Not AllowedContent-Type: application/jsonContent-Length: 42{'detail': 'Method ’DELETE’ not allowed.'}
校驗(yàn)錯(cuò)誤的處理有些輕微的不同,它會(huì)把字段的名字作為鍵包含進(jìn)來。如果校驗(yàn)錯(cuò)誤沒有被指定到一個(gè)特定的字段,那么它會(huì)使用non_field_errors作為鍵,或者是你在setting文件中設(shè)定的NON_FIELD_ERRORS_KEY任意字符串的值。
任何校驗(yàn)錯(cuò)誤將類似下面的形式:
HTTP/1.1 400 Bad RequestContent-Type: application/jsonContent-Length: 94{'amount': ['A valid integer is required.'], 'description': ['This field may not be blank.']}
自定義異常處理
你可以實(shí)現(xiàn)你的自定義異常處理。可以通過創(chuàng)建一個(gè)異常處理函數(shù)將API視圖中拋出的異常轉(zhuǎn)換成響應(yīng)對象。這樣一來,你就可以控制你的API使用的錯(cuò)誤響應(yīng)格式。
這個(gè)異常處理函數(shù)必須傳入兩個(gè)參數(shù),第一個(gè)是要處理的異常,第二個(gè)是一個(gè)包含了任何額外上下文信息(例如當(dāng)前被處理的視圖)的字典。該異常處理函數(shù)要么返回一個(gè)Response對象,要么在異常無法處理的時(shí)候返回None。如果返回了None,異常將會(huì)被重新拋出,最后Django會(huì)返回一個(gè)標(biāo)準(zhǔn)的HTTP 500 ‘服務(wù)器錯(cuò)誤’的響應(yīng)。
例如,你可能希望保證所有的錯(cuò)誤響應(yīng)體中都包含了HTTP狀態(tài)碼,像這樣:
HTTP/1.1 405 Method Not AllowedContent-Type: application/jsonContent-Length: 62{'status_code': 405, 'detail': 'Method ’DELETE’ not allowed.'}
為了更改響應(yīng)的格式,你可以編寫如下的自定義異常處理函數(shù):
from rest_framework.views import exception_handlerdef custom_exception_handler(exc, context): # Call REST framework’s default exception handler first, # to get the standard error response. response = exception_handler(exc, context) # Now add the HTTP status code to the response. if response is not None: response.data[’status_code’] = response.status_code return response
參數(shù)context沒有被默認(rèn)的異常處理器使用,但是如果你需要更多的信息,例如你想獲得當(dāng)前被處理的視圖,它就能給你援助之手了。通過context[’view’]就可以獲取當(dāng)前視圖。
同時(shí)你必須在你的settings中配置異常處理器,顯式地給EXCEPTION_HANDLER設(shè)置你期望的值,例如:
REST_FRAMEWORK = { ’EXCEPTION_HANDLER’: ’my_project.my_app.utils.custom_exception_handler’}
如果沒有指定,’EXCEPTION_HANDLER‘默認(rèn)使用的是REST框架提供的標(biāo)準(zhǔn)的異常處理器:
REST_FRAMEWORK = { ’EXCEPTION_HANDLER’: ’rest_framework.views.exception_handler’}
注意一點(diǎn),異常處理器僅僅在響應(yīng)是由拋出的異常產(chǎn)生時(shí)被調(diào)用。如果由視圖直接返回的響應(yīng),它將不會(huì)被調(diào)用,例如HTTP_400_BAD_REQUEST響應(yīng)是在序列化校驗(yàn)失敗時(shí)由generic視圖返回的,此時(shí)異常處理器就不會(huì)被調(diào)用。
API 引用
APIException
Signature: APIException()
所有在APIView類中或者@api_view拋出的異常的基類。
為了提供自定義異常,自定義個(gè)類,繼承自APIException,并設(shè)置.status_code和.default_detail屬性。
例如,如果你的API依賴第三方服務(wù),這個(gè)服務(wù)有時(shí)候可能會(huì)不可用,你或許可以考慮為”503 Service Unavailable”HTTP響應(yīng)碼實(shí)現(xiàn)一個(gè)異常類,你可以這么做:
from rest_framework.exceptions import APIExceptionclass ServiceUnavailable(APIException): status_code = 503 default_detail = ’Service temporarily unavailable, try again later.’
ParseError
Signature: ParseError(detail=None)
在訪問request.data的時(shí)候,如果請求包含了非法的數(shù)據(jù),就會(huì)拋出該錯(cuò)誤。
默認(rèn),該異常返回”400 Bad Request”狀態(tài)碼。
AuthenticationFailed
Signature: AuthenticationFailed(detail=None)
當(dāng)請求包含了錯(cuò)誤的認(rèn)證信息的時(shí)候拋出。
Raised when an incoming request includes incorrect authentication.
默認(rèn)情況下,該異常返回401 Unauthenticated,但是也有可能返回403 Forbidden,這取決于使用的認(rèn)證模式。詳細(xì)內(nèi)容參考authentication documentation
NotAuthenticated
Signature: NotAuthenticated(detail=None)
當(dāng)未認(rèn)證的請求權(quán)限驗(yàn)證失敗時(shí)拋出。
默認(rèn)情況下,該異常返回401 Unauthenticated,但是也有可能返回403 Forbidden,這取決于使用的認(rèn)證模式。詳細(xì)內(nèi)容參考authentication documentation
PermissionDenied
Signature: PermissionDenied(detail=None)
當(dāng)一個(gè)經(jīng)認(rèn)證的請求在權(quán)限校驗(yàn)失敗時(shí)拋出。
默認(rèn)返回403 Forbidden
NotFound
Signature: NotFound(detail=None)
當(dāng)給定的URL不存在時(shí)拋出。該異常等效于標(biāo)準(zhǔn)的DjangoHttp404異常。
默認(rèn)返回404 Not Found.
MethodNotAllowed
Signature: MethodNotAllowed(method, detail=None)
在視圖中沒有與請求匹配的處理方法時(shí)拋出。
默認(rèn)返回405 Method Not Allowed
NotAcceptable
Signature: NotAcceptable(detail=None)
當(dāng)請求的接受頭不滿足任何可用的渲染器時(shí)拋出。
默認(rèn)返回406 Not Acceptable
UnsupportedMediaType
Signature: UnsupportedMediaType(media_type, detail=None)
當(dāng)訪問request.data時(shí),沒有解析器來處理請求數(shù)據(jù)的內(nèi)容類型時(shí)拋出。
默認(rèn)返回415 Unsupported Media Type
Throttled
Signature: Throttled(wait=None, detail=None)
當(dāng)請求超過最大限制時(shí)拋出。
默認(rèn)返回429 Too Many Requests
ValidationError
Signature: ValidationError(detail)
ValidationError跟其他的APIException類稍微有些不同:
The ValidationError exception is slightly different from the other APIException classes:
detail參數(shù)是強(qiáng)制的,非可選。
detail參數(shù)可以是錯(cuò)誤細(xì)節(jié)的列表或者字典,也可以是一個(gè)內(nèi)嵌的數(shù)據(jù)結(jié)構(gòu)。
約定中,你應(yīng)該導(dǎo)入序列化器模塊并使用完整描述的ValidationError格式,這是為了跟Django的內(nèi)置檢驗(yàn)錯(cuò)誤區(qū)分開來。例如.raise serializers.ValidationError(’This field must be an integer value.’)
ValidationError類應(yīng)該通過驗(yàn)證器類為序列化器和字段校驗(yàn)使用。它也會(huì)在調(diào)用serializer.is_valid方法,并指定了raise_exception時(shí)被拋出。
serializer.is_valid(raise_exception=True)
在generic視圖中使用raise_exception=True標(biāo)記,意味著你可以在你的API中全局復(fù)寫校驗(yàn)錯(cuò)誤響應(yīng)的格式。如果你要這么做,建議你使用一個(gè)自定義的異常,上文有描述。
默認(rèn)情況下,該異常返回400 Bad Request
更多閱讀官方原文鏈接
以上這篇Django REST 異常處理詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. html小技巧之td,div標(biāo)簽里內(nèi)容不換行2. webpack高級配置與優(yōu)化詳解3. css代碼優(yōu)化的12個(gè)技巧4. CSS3中Transition屬性詳解以及示例分享5. ASP常用日期格式化函數(shù) FormatDate()6. Xml簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理7. 怎樣才能用js生成xmldom對象,并且在firefox中也實(shí)現(xiàn)xml數(shù)據(jù)島?8. HTML <!DOCTYPE> 標(biāo)簽9. 得到XML文檔大小的方法10. HTML DOM setInterval和clearInterval方法案例詳解
