Coverage for fastapi/exceptions.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-08 03:53 +0000

1from typing import Any, Dict, Optional, Sequence, Type, Union 1abcde

2 

3from pydantic import BaseModel, create_model 1abcde

4from starlette.exceptions import HTTPException as StarletteHTTPException 1abcde

5from starlette.exceptions import WebSocketException as StarletteWebSocketException 1abcde

6from typing_extensions import Annotated, Doc 1abcde

7 

8 

9class HTTPException(StarletteHTTPException): 1abcde

10 """ 

11 An HTTP exception you can raise in your own code to show errors to the client. 

12 

13 This is for client errors, invalid authentication, invalid data, etc. Not for server 

14 errors in your code. 

15 

16 Read more about it in the 

17 [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). 

18 

19 ## Example 

20 

21 ```python 

22 from fastapi import FastAPI, HTTPException 

23 

24 app = FastAPI() 

25 

26 items = {"foo": "The Foo Wrestlers"} 

27 

28 

29 @app.get("/items/{item_id}") 

30 async def read_item(item_id: str): 

31 if item_id not in items: 

32 raise HTTPException(status_code=404, detail="Item not found") 

33 return {"item": items[item_id]} 

34 ``` 

35 """ 

36 

37 def __init__( 1abcde

38 self, 

39 status_code: Annotated[ 

40 int, 

41 Doc( 

42 """ 

43 HTTP status code to send to the client. 

44 """ 

45 ), 

46 ], 

47 detail: Annotated[ 

48 Any, 

49 Doc( 

50 """ 

51 Any data to be sent to the client in the `detail` key of the JSON 

52 response. 

53 """ 

54 ), 

55 ] = None, 

56 headers: Annotated[ 

57 Optional[Dict[str, str]], 

58 Doc( 

59 """ 

60 Any headers to send to the client in the response. 

61 """ 

62 ), 

63 ] = None, 

64 ) -> None: 

65 super().__init__(status_code=status_code, detail=detail, headers=headers) 1abcde

66 

67 

68class WebSocketException(StarletteWebSocketException): 1abcde

69 """ 

70 A WebSocket exception you can raise in your own code to show errors to the client. 

71 

72 This is for client errors, invalid authentication, invalid data, etc. Not for server 

73 errors in your code. 

74 

75 Read more about it in the 

76 [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). 

77 

78 ## Example 

79 

80 ```python 

81 from typing import Annotated 

82 

83 from fastapi import ( 

84 Cookie, 

85 FastAPI, 

86 WebSocket, 

87 WebSocketException, 

88 status, 

89 ) 

90 

91 app = FastAPI() 

92 

93 @app.websocket("/items/{item_id}/ws") 

94 async def websocket_endpoint( 

95 *, 

96 websocket: WebSocket, 

97 session: Annotated[str | None, Cookie()] = None, 

98 item_id: str, 

99 ): 

100 if session is None: 

101 raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) 

102 await websocket.accept() 

103 while True: 

104 data = await websocket.receive_text() 

105 await websocket.send_text(f"Session cookie is: {session}") 

106 await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}") 

107 ``` 

108 """ 

109 

110 def __init__( 1abcde

111 self, 

112 code: Annotated[ 

113 int, 

114 Doc( 

115 """ 

116 A closing code from the 

117 [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1). 

118 """ 

119 ), 

120 ], 

121 reason: Annotated[ 

122 Union[str, None], 

123 Doc( 

124 """ 

125 The reason to close the WebSocket connection. 

126 

127 It is UTF-8-encoded data. The interpretation of the reason is up to the 

128 application, it is not specified by the WebSocket specification. 

129 

130 It could contain text that could be human-readable or interpretable 

131 by the client code, etc. 

132 """ 

133 ), 

134 ] = None, 

135 ) -> None: 

136 super().__init__(code=code, reason=reason) 1abcde

137 

138 

139RequestErrorModel: Type[BaseModel] = create_model("Request") 1abcde

140WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket") 1abcde

141 

142 

143class FastAPIError(RuntimeError): 1abcde

144 """ 

145 A generic, FastAPI-specific error. 

146 """ 

147 

148 

149class ValidationException(Exception): 1abcde

150 def __init__(self, errors: Sequence[Any]) -> None: 1abcde

151 self._errors = errors 1abcde

152 

153 def errors(self) -> Sequence[Any]: 1abcde

154 return self._errors 1abcde

155 

156 

157class RequestValidationError(ValidationException): 1abcde

158 def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None: 1abcde

159 super().__init__(errors) 1abcde

160 self.body = body 1abcde

161 

162 

163class WebSocketRequestValidationError(ValidationException): 1abcde

164 pass 1abcde

165 

166 

167class ResponseValidationError(ValidationException): 1abcde

168 def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None: 1abcde

169 super().__init__(errors) 1abcde

170 self.body = body 1abcde

171 

172 def __str__(self) -> str: 1abcde

173 message = f"{len(self._errors)} validation errors:\n" 1abcde

174 for err in self._errors: 1abcde

175 message += f" {err}\n" 1abcde

176 return message 1abcde