File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ from .errors import (
2+ AuthenticationError ,
3+ InvalidRequestError ,
4+ NetworkError ,
5+ NotFoundError ,
6+ ShadeError ,
7+ )
18from .gateway import Gateway
29
310__version__ = "0.1.0"
411
5- __all__ = ["Gateway" ]
12+ __all__ = [
13+ "AuthenticationError" ,
14+ "Gateway" ,
15+ "InvalidRequestError" ,
16+ "NetworkError" ,
17+ "NotFoundError" ,
18+ "ShadeError" ,
19+ ]
Original file line number Diff line number Diff line change 1+ from __future__ import annotations
2+
3+ from typing import Optional
4+
5+
6+ class ShadeError (Exception ):
7+ """Base exception for all Shade SDK errors."""
8+
9+ def __init__ (
10+ self ,
11+ message : str ,
12+ status_code : Optional [int ] = None ,
13+ response_body : Optional [str ] = None ,
14+ ) -> None :
15+ self .message = message
16+ self .status_code = status_code
17+ self .response_body = response_body
18+ super ().__init__ (message )
19+
20+ def __str__ (self ) -> str :
21+ if self .status_code is None :
22+ return self .message
23+ return f"{ self .message } (status code: { self .status_code } )"
24+
25+
26+ class AuthenticationError (ShadeError ):
27+ """Raised when authentication fails or credentials are invalid."""
28+
29+
30+ class InvalidRequestError (ShadeError ):
31+ """Raised when a request is malformed or rejected by validation."""
32+
33+
34+ class NotFoundError (ShadeError ):
35+ """Raised when an API resource cannot be found."""
36+
37+
38+ class NetworkError (ShadeError ):
39+ """Raised when the SDK cannot complete a network request."""
Original file line number Diff line number Diff line change 1+ import shade
2+ from shade import (
3+ AuthenticationError ,
4+ InvalidRequestError ,
5+ NetworkError ,
6+ NotFoundError ,
7+ ShadeError ,
8+ )
9+
10+
11+ def test_shade_error_can_be_raised_standalone ():
12+ error = ShadeError ("contract rejected payment" )
13+
14+ assert str (error ) == "contract rejected payment"
15+ assert error .message == "contract rejected payment"
16+ assert error .status_code is None
17+ assert error .response_body is None
18+
19+
20+ def test_shade_error_includes_http_context ():
21+ error = ShadeError (
22+ "invalid request" ,
23+ status_code = 422 ,
24+ response_body = '{"error":"missing amount"}' ,
25+ )
26+
27+ assert str (error ) == "invalid request (status code: 422)"
28+ assert error .status_code == 422
29+ assert error .response_body == '{"error":"missing amount"}'
30+
31+
32+ def test_specific_errors_inherit_from_shade_error ():
33+ for error_type in (
34+ AuthenticationError ,
35+ InvalidRequestError ,
36+ NetworkError ,
37+ NotFoundError ,
38+ ):
39+ error = error_type ("request failed" , status_code = 400 , response_body = "raw" )
40+
41+ assert isinstance (error , ShadeError )
42+ assert str (error ) == "request failed (status code: 400)"
43+ assert error .response_body == "raw"
44+
45+
46+ def test_package_root_exports_error_classes ():
47+ assert shade .ShadeError is ShadeError
48+ assert shade .AuthenticationError is AuthenticationError
49+ assert shade .InvalidRequestError is InvalidRequestError
50+ assert shade .NetworkError is NetworkError
51+ assert shade .NotFoundError is NotFoundError
You can’t perform that action at this time.
0 commit comments