Coverage for src/fastapi_cloud_cli/api/_errors.py: 100%

70 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-11-09 00:25 +0000

1import json 2PdQdRdSdTdUdVd

2import logging 2PdQdRdSdTdUdVd

3 

4import httpx 2PdQdRdSdTdUdVd

5 

6from fastapi_cloud_cli.utils.auth import AuthMode, delete_auth_config 2PdQdRdSdTdUdVd

7from fastapi_cloud_cli.utils.errors import ErrorCode 2PdQdRdSdTdUdVd

8 

9logger = logging.getLogger(__name__) 2PdQdRdSdTdUdVd

10 

11 

12class StreamLogError(Exception): 2PdQdRdSdTdUdVd

13 """Raised when there's an error streaming logs (build or app logs).""" 

14 

15 def __init__(self, message: str, *, status_code: int | None = None) -> None: 2PdQdRdSdTdUdVd

16 super().__init__(message) 2Pd;d=do ?dp q @dSbTb[dQd]d^dr _ds t `dUbVb{dRd|d}du ~dv w aeWbXbbeSdcedex eey z feYbZbgeTdheieA jeB C ke0b1bleUdmeneD oeE F pe2b3bqeVdreseG teH I ue4b5bve

17 self.status_code = status_code 2Pd;d=do ?dp q @dSbTb[dQd]d^dr _ds t `dUbVb{dRd|d}du ~dv w aeWbXbbeSdcedex eey z feYbZbgeTdheieA jeB C ke0b1bleUdmeneD oeE F pe2b3bqeVdreseG teH I ue4b5bve

18 

19 

20class TooManyRetriesError(Exception): 2PdQdRdSdTdUdVd

21 pass 2PdQdRdSdTdUdVd

22 

23 

24def _handle_unauthorized(auth_mode: AuthMode) -> str: 2PdQdRdSdTdUdVd

25 message = "The specified token is not valid. " 2Nc]bo qb^bp Oc_br rb`bs Pc{bu sb|bv Qc}bx tb~by RcacA ubbcB ScccD vbdcE TcecG wbfcH

26 

27 if auth_mode == "user": 2Nc]bo qb^bp Oc_br rb`bs Pc{bu sb|bv Qc}bx tb~by RcacA ubbcB ScccD vbdcE TcecG wbfcH

28 delete_auth_config() 2]bo qb^bp _br rb`bs {bu sb|bv }bx tb~by acA ubbcB ccD vbdcE ecG wbfcH

29 

30 message += "Use `fastapi login` to generate a new token." 2]bo qb^bp _br rb`bs {bu sb|bv }bx tb~by acA ubbcB ccD vbdcE ecG wbfcH

31 else: 

32 message += "Make sure to use a valid token." 2NcOcPcQcRcScTc

33 

34 return message 2Nc]bo qb^bp Oc_br rb`bs Pc{bu sb|bv Qc}bx tb~by RcacA ubbcB ScccD vbdcE TcecG wbfcH

35 

36 

37def _get_response_error_message(response: httpx.Response) -> str | None: 2PdQdRdSdTdUdVd

38 try: 26bgcJ a hcK L M N O P 3d4dIdxbQ R yb7bUczb8bb icS jcq SbTbkclcT c mcU V W X Y Z 5d6dJdAb0 1 Bb9bVcCb!bd nc2 oct UbVbpcqc3 e rc4 5 6 7 8 9 7d8dKdDb! # Eb#bWcFb$bf sc$ tcw WbXbucvc% g wc' ( ) * + , 9d!dLdGb- . Hb%bXcIb'bh xc/ ycz YbZb(bzc: i Ac; = ? @ [ ] #d$dMdJb^ _ Kb)bYcLb*bj Bc` CcC 0b1bDcEc{ k Fc| } ~ abbbcb%d'dNdMbdbebNb+bZcOb,bl GcfbHcF 2b3bIcJcgbm Kchbibjbkblbmb(d)dOdPbnbobQb-b0cRb.bn LcpbMcI 4b5b

39 data = response.json() 26bgcJ a hcK L M N O P 3d4dIdxbQ R yb7bUczb8bb icS jcq SbTbkclcT c mcU V W X Y Z 5d6dJdAb0 1 Bb9bVcCb!bd nc2 oct UbVbpcqc3 e rc4 5 6 7 8 9 7d8dKdDb! # Eb#bWcFb$bf sc$ tcw WbXbucvc% g wc' ( ) * + , 9d!dLdGb- . Hb%bXcIb'bh xc/ ycz YbZb(bzc: i Ac; = ? @ [ ] #d$dMdJb^ _ Kb)bYcLb*bj Bc` CcC 0b1bDcEc{ k Fc| } ~ abbbcb%d'dNdMbdbebNb+bZcOb,bl GcfbHcF 2b3bIcJcgbm Kchbibjbkblbmb(d)dOdPbnbobQb-b0cRb.bn LcpbMcI 4b5b

40 except (json.JSONDecodeError, httpx.ResponseNotRead): 2K L M N O P IdQ R ybzb8bq U V W X Y Z Jd0 1 BbCb!bt 4 5 6 7 8 9 Kd! # EbFb$bw ' ( ) * + , Ld- . HbIb'bz ; = ? @ [ ] Md^ _ KbLb*bC | } ~ abbbcbNddbebNbOb,bF hbibjbkblbmbOdnbobQbRb.bI

41 return None 2K L M N O P IdQ R ybzb8bq U V W X Y Z Jd0 1 BbCb!bt 4 5 6 7 8 9 Kd! # EbFb$bw ' ( ) * + , Ld- . HbIb'bz ; = ? @ [ ] Md^ _ KbLb*bC | } ~ abbbcbNddbebNbOb,bF hbibjbkblbmbOdnbobQbRb.bI

42 

43 if not isinstance(data, dict): 26bgcJ a hc3d4dxb7bUcb icS jcSbTbkclcT c mc5d6dAb9bVcd nc2 ocUbVbpcqc3 e rc7d8dDb#bWcf sc$ tcWbXbucvc% g wc9d!dGb%bXch xc/ ycYbZb(bzc: i Ac#d$dJb)bYcj Bc` Cc0b1bDcEc{ k Fc%d'dMb+bZcl GcfbHc2b3bIcJcgbm Kc(d)dPb-b0cn LcpbMc4b5b

44 return None # pragma: no cover 

45 

46 detail = data.get("detail") 26bgcJ a hc3d4dxb7bUcb icS jcSbTbkclcT c mc5d6dAb9bVcd nc2 ocUbVbpcqc3 e rc7d8dDb#bWcf sc$ tcWbXbucvc% g wc9d!dGb%bXch xc/ ycYbZb(bzc: i Ac#d$dJb)bYcj Bc` Cc0b1bDcEc{ k Fc%d'dMb+bZcl GcfbHc2b3bIcJcgbm Kc(d)dPb-b0cn LcpbMc4b5b

47 if isinstance(detail, str): 26bgcJ a hc3d4dxb7bUcb icS jcSbTbkclcT c mc5d6dAb9bVcd nc2 ocUbVbpcqc3 e rc7d8dDb#bWcf sc$ tcWbXbucvc% g wc9d!dGb%bXch xc/ ycYbZb(bzc: i Ac#d$dJb)bYcj Bc` Cc0b1bDcEc{ k Fc%d'dMb+bZcl GcfbHc2b3bIcJcgbm Kc(d)dPb-b0cn LcpbMc4b5b

48 return detail 2gcJ a hc3d4dxb7bUcb icS jcSbTblcT c mc5d6dAb9bVcd nc2 ocUbVbqc3 e rc7d8dDb#bWcf sc$ tcWbXbvc% g wc9d!dGb%bXch xc/ ycYbZbzc: i Ac#d$dJb)bYcj Bc` Cc0b1bEc{ k Fc%d'dMb+bZcl GcfbHc2b3bJcgbm Kc(d)dPb-b0cn LcpbMc4b5b

49 

50 if ( 26b(b

51 isinstance(detail, list) 

52 and detail 

53 and isinstance(detail[0], dict) 

54 and isinstance(message := detail[0].get("msg"), str) 

55 ): 

56 return message.removeprefix("Value error, ") 26bkcpcuc(bDcIc

57 

58 return None # pragma: no cover 

59 

60 

61def handle_http_error( 2PdQdRdSdTdUdVd

62 error: httpx.HTTPError, 

63 default_message: str | None = None, 

64 not_found_message: str | None = None, 

65 auth_mode: AuthMode = "user", 

66) -> str: 

67 message: str | None = None 26bgcJ a WdhcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c XdmcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e Ydrc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g Zdwc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i 0dAc; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k 1dFc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm 2dKchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

68 

69 if isinstance(error, httpx.HTTPStatusError): 26bgcJ a WdhcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c XdmcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e Ydrc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g Zdwc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i 0dAc; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k 1dFc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm 2dKchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

70 status_code = error.response.status_code 26bgcJ a hcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c mcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e rc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g wc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i Ac; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k Fc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm KchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

71 

72 if status_code == 422: 26bgcJ a hcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c mcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e rc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g wc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i Ac; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k Fc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm KchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

73 logger.debug(error.response.json()) 26bkcpcuc(bDcIc

74 message = _get_response_error_message(error.response) 26bkcpcuc(bDcIc

75 

76 elif status_code == 400: 2gcJ a hcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTblcT c mcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbqc3 e rc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbvc% g wc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZbzc: i Ac; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bEc{ k Fc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bJcgbm KchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

77 message = _get_response_error_message(error.response) 2gchcIdicjcSbTblcmcJdncocUbVbqcrcKdsctcWbXbvcwcLdxcycYbZbzcAcMdBcCc0b1bEcFcNdGcHc2b3bJcKcOdLcMc4b5b

78 

79 elif status_code == 409: 2J a K L M N O P Nc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb 8cS 9c!cp q T c U V W X Y Z Oc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd +c2 ,c-cs t 3 e 4 5 6 7 8 9 Pc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf [c$ ]c^cv w % g ' ( ) * + , Qc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh bd/ cdddy z : i ; = ? @ [ ] RcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj ld` mdndB C { k | } ~ abbbcbScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl vdfbwdxdE F gbm hbibjbkblbmbTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn FdpbGdHdH I

80 message = _get_response_error_message(error.response) 27bUc9bVc#bWc%bXc)bYc+bZc-b0c

81 

82 elif status_code == 401: 2J a K L M N O P Nc]bxb1c2cQ o 3c4c5cR yb6c/bqbzb7c^b8bb 8cS 9c!cp q T c U V W X Y Z Oc_bAb#c$c0 r %c'c(c1 Bb)c:brbCb*c`b!bd +c2 ,c-cs t 3 e 4 5 6 7 8 9 Pc{bDb.c/c! u :c;c=c# Eb?c;bsbFb@c|b$bf [c$ ]c^cv w % g ' ( ) * + , Qc}bGb_c`c- x {c|c}c. Hb~c=btbIbad~b'bh bd/ cdddy z : i ; = ? @ [ ] RcacJbedfd^ A gdhdid_ Kbjd?bubLbkdbc*bj ld` mdndB C { k | } ~ abbbcbScccMbodpddbD qdrdsdebNbtd@bvbObuddc,bl vdfbwdxdE F gbm hbibjbkblbmbTcecPbydzdnbG AdBdCdobQbDd[bwbRbEdfc.bn FdpbGdHdH I

83 message = _handle_unauthorized(auth_mode=auth_mode) 2Nc]bo qb^bp Oc_br rb`bs Pc{bu sb|bv Qc}bx tb~by RcacA ubbcB ScccD vbdcE TcecG wbfcH

84 

85 elif status_code == 403: 2J a K L M N O P xb1c2cQ 3c4c5cR yb6c/bzb7c8bb 8cS 9c!cq T c U V W X Y Z Ab#c$c0 %c'c(c1 Bb)c:bCb*c!bd +c2 ,c-ct 3 e 4 5 6 7 8 9 Db.c/c! :c;c=c# Eb?c;bFb@c$bf [c$ ]c^cw % g ' ( ) * + , Gb_c`c- {c|c}c. Hb~c=bIbad'bh bd/ cdddz : i ; = ? @ [ ] Jbedfd^ gdhdid_ Kbjd?bLbkd*bj ld` mdndC { k | } ~ abbbcbMbodpddbqdrdsdebNbtd@bObud,bl vdfbwdxdF gbm hbibjbkblbmbPbydzdnbAdBdCdobQbDd[bRbEd.bn FdpbGdHdI

86 message = ( 2J xbybzb8bq T AbBbCb!bt 3 DbEbFb$bw % GbHbIb'bz : JbKbLb*bC { MbNbOb,bF gbPbQbRb.bI

87 _get_response_error_message(error.response) 

88 or "You don't have permissions for this resource" 

89 ) 

90 

91 elif status_code == 404: 2a K L M N O P 1c2cQ 3c4c5cR 6c/b7cb 8cS 9c!cc U V W X Y Z #c$c0 %c'c(c1 )c:b*cd +c2 ,c-ce 4 5 6 7 8 9 .c/c! :c;c=c# ?c;b@cf [c$ ]c^cg ' ( ) * + , _c`c- {c|c}c. ~c=badh bd/ cdddi ; = ? @ [ ] edfd^ gdhdid_ jd?bkdj ld` mdndk | } ~ abbbcbodpddbqdrdsdebtd@budl vdfbwdxdm hbibjbkblbmbydzdnbAdBdCdobDd[bEdn FdpbGdHd

92 message = ( 2a K L M N O P Q R b S c U V W X Y Z 0 1 d 2 e 4 5 6 7 8 9 ! # f $ g ' ( ) * + , - . h / i ; = ? @ [ ] ^ _ j ` k | } ~ abbbcbdbebl fbm hbibjbkblbmbnbobn pb

93 _get_response_error_message(error.response) 

94 or not_found_message 

95 or "Resource not found." 

96 ) 

97 

98 if not message: 26bgcJ a WdhcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c XdmcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e Ydrc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g Zdwc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i 0dAc; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k 1dFc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm 2dKchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

99 message = ( 2WdId1c2c3c4c5c6c/b7c8c9c!cXdJd#c$c%c'c(c)c:b*c+c,c-cYdKd.c/c:c;c=c?c;b@c[c]c^cZdLd_c`c{c|c}c~c=badbdcddd0dMdedfdgdhdidjd?bkdldmdnd1dNdodpdqdrdsdtd@budvdwdxd2dOdydzdAdBdCdDd[bEdFdGdHd

100 default_message 

101 or f"Something went wrong while contacting the FastAPI Cloud server. Please try again later. \n\n{error}" 

102 ) 

103 

104 return message 26bgcJ a WdhcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c XdmcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e Ydrc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g Zdwc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i 0dAc; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k 1dFc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm 2dKchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

105 

106 

107def get_http_error_code(error: httpx.HTTPError) -> ErrorCode: 2PdQdRdSdTdUdVd

108 if isinstance(error, httpx.TimeoutException | httpx.NetworkError): 26bgcJ a WdhcK L M N O weP IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c XdmcU V W X Y xeZ JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e Ydrc4 5 6 7 8 ye9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g Zdwc' ( ) * + ze, LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i 0dAc; = ? @ [ Ae] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k 1dFc| } ~ abbbBecbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm 2dKchbibjbkblbCembOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

109 return "network_error" 2WdweXdxeYdyeZdze0dAe1dBe2dCe

110 

111 if isinstance(error, httpx.HTTPStatusError): 26bgcJ a hcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c mcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e rc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g wc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i Ac; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k Fc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm KchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

112 status_code = error.response.status_code 26bgcJ a hcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c mcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e rc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g wc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i Ac; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k Fc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm KchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

113 

114 if status_code in {400, 409, 422}: 26bgcJ a hcK L M N O P IdNc]bxb1c2cQ o 3c4c5cR yb6c7bUc/bqbzb7c^b8bb ic8cS 9cjc!cp q SbTbkclcT c mcU V W X Y Z JdOc_bAb#c$c0 r %c'c(c1 Bb)c9bVc:brbCb*c`b!bd nc+c2 ,coc-cs t UbVbpcqc3 e rc4 5 6 7 8 9 KdPc{bDb.c/c! u :c;c=c# Eb?c#bWc;bsbFb@c|b$bf sc[c$ ]ctc^cv w WbXbucvc% g wc' ( ) * + , LdQc}bGb_c`c- x {c|c}c. Hb~c%bXc=btbIbad~b'bh xcbd/ cdycddy z YbZb(bzc: i Ac; = ? @ [ ] MdRcacJbedfd^ A gdhdid_ Kbjd)bYc?bubLbkdbc*bj Bcld` mdCcndB C 0b1bDcEc{ k Fc| } ~ abbbcbNdScccMbodpddbD qdrdsdebNbtd+bZc@bvbObuddc,bl GcvdfbwdHcxdE F 2b3bIcJcgbm KchbibjbkblbmbOdTcecPbydzdnbG AdBdCdobQbDd-b0c[bwbRbEdfc.bn LcFdpbGdMcHdH I 4b5b

115 return "invalid_input" 26bgchcId7bUcicjcSbTbkclcmcJd9bVcncocUbVbpcqcrcKd#bWcsctcWbXbucvcwcLd%bXcxcycYbZb(bzcAcMd)bYcBcCc0b1bDcEcFcNd+bZcGcHc2b3bIcJcKcOd-b0cLcMc4b5b

116 

117 if status_code == 401: 2J a K L M N O P Nc]bxb1c2cQ o 3c4c5cR yb6c/bqbzb7c^b8bb 8cS 9c!cp q T c U V W X Y Z Oc_bAb#c$c0 r %c'c(c1 Bb)c:brbCb*c`b!bd +c2 ,c-cs t 3 e 4 5 6 7 8 9 Pc{bDb.c/c! u :c;c=c# Eb?c;bsbFb@c|b$bf [c$ ]c^cv w % g ' ( ) * + , Qc}bGb_c`c- x {c|c}c. Hb~c=btbIbad~b'bh bd/ cdddy z : i ; = ? @ [ ] RcacJbedfd^ A gdhdid_ Kbjd?bubLbkdbc*bj ld` mdndB C { k | } ~ abbbcbScccMbodpddbD qdrdsdebNbtd@bvbObuddc,bl vdfbwdxdE F gbm hbibjbkblbmbTcecPbydzdnbG AdBdCdobQbDd[bwbRbEdfc.bn FdpbGdHdH I

118 return "invalid_token" 2Nc]bo qb^bp Oc_br rb`bs Pc{bu sb|bv Qc}bx tb~by RcacA ubbcB ScccD vbdcE TcecG wbfcH

119 

120 if status_code == 403: 2J a K L M N O P xb1c2cQ 3c4c5cR yb6c/bzb7c8bb 8cS 9c!cq T c U V W X Y Z Ab#c$c0 %c'c(c1 Bb)c:bCb*c!bd +c2 ,c-ct 3 e 4 5 6 7 8 9 Db.c/c! :c;c=c# Eb?c;bFb@c$bf [c$ ]c^cw % g ' ( ) * + , Gb_c`c- {c|c}c. Hb~c=bIbad'bh bd/ cdddz : i ; = ? @ [ ] Jbedfd^ gdhdid_ Kbjd?bLbkd*bj ld` mdndC { k | } ~ abbbcbMbodpddbqdrdsdebNbtd@bObud,bl vdfbwdxdF gbm hbibjbkblbmbPbydzdnbAdBdCdobQbDd[bRbEd.bn FdpbGdHdI

121 return "permission_denied" 2J xbybzb8bq T AbBbCb!bt 3 DbEbFb$bw % GbHbIb'bz : JbKbLb*bC { MbNbOb,bF gbPbQbRb.bI

122 

123 if status_code == 404: 2a K L M N O P 1c2cQ 3c4c5cR 6c/b7cb 8cS 9c!cc U V W X Y Z #c$c0 %c'c(c1 )c:b*cd +c2 ,c-ce 4 5 6 7 8 9 .c/c! :c;c=c# ?c;b@cf [c$ ]c^cg ' ( ) * + , _c`c- {c|c}c. ~c=badh bd/ cdddi ; = ? @ [ ] edfd^ gdhdid_ jd?bkdj ld` mdndk | } ~ abbbcbodpddbqdrdsdebtd@budl vdfbwdxdm hbibjbkblbmbydzdnbAdBdCdobDd[bEdn FdpbGdHd

124 return "not_found" 2a K L M N O P Q R b S c U V W X Y Z 0 1 d 2 e 4 5 6 7 8 9 ! # f $ g ' ( ) * + , - . h / i ; = ? @ [ ] ^ _ j ` k | } ~ abbbcbdbebl fbm hbibjbkblbmbnbobn pb

125 

126 return "api_error" 21c2c3c4c5c6c/b7c8c9c!c#c$c%c'c(c)c:b*c+c,c-c.c/c:c;c=c?c;b@c[c]c^c_c`c{c|c}c~c=badbdcdddedfdgdhdidjd?bkdldmdndodpdqdrdsdtd@budvdwdxdydzdAdBdCdDd[bEdFdGdHd

127 

128 

129def get_http_error_hint(code: ErrorCode, *, auth_mode: AuthMode = "user") -> str | None: 2PdQdRdSdTdUdVd

130 if code == "invalid_token": 26bgcJ a WdhcK L M N O *dP Q o R yb7b/bqbzbb icjcp q SbTbkclcT c XdmcU V W X Y +dZ 0 r 1 Bb9b:brbCbd ncocs t UbVbpcqc3 e Ydrc4 5 6 7 8 ,d9 ! u # Eb#b;bsbFbf sctcv w WbXbucvc% g Zdwc' ( ) * + -d, - x . Hb%b=btbIbh xcycy z YbZb(bzc: i 0dAc; = ? @ [ .d] ^ A _ Kb)b?bubLbj BcCcB C 0b1bDcEc{ k 1dFc| } ~ abbb/dcbdbD ebNb+b@bvbObl GcHcE F 2b3bIcJcgbm 2dKchbibjbkblb:dmbnbG obQb-b[bwbRbn LcMcH I 4b5b

131 if auth_mode == "user": 2*do qbp +dr rbs ,du sbv -dx tby .dA ubB /dD vbE :dG wbH

132 return "Run `fastapi cloud login` to generate a new token." 2o qbp r rbs u sbv x tby A ubB D vbE G wbH

133 

134 return "Make sure FASTAPI_CLOUD_TOKEN contains a valid token." 2*d+d,d-d.d/d:d

135 

136 return None 26bgcJ a WdhcK L M N O P Q R yb7b/bzbb icjcq SbTbkclcT c XdmcU V W X Y Z 0 1 Bb9b:bCbd ncoct UbVbpcqc3 e Ydrc4 5 6 7 8 9 ! # Eb#b;bFbf sctcw WbXbucvc% g Zdwc' ( ) * + , - . Hb%b=bIbh xcycz YbZb(bzc: i 0dAc; = ? @ [ ] ^ _ Kb)b?bLbj BcCcC 0b1bDcEc{ k 1dFc| } ~ abbbcbdbebNb+b@bObl GcHcF 2b3bIcJcgbm 2dKchbibjbkblbmbnbobQb-b[bRbn LcMcI 4b5b