1use thiserror::Error;
6
7#[derive(Debug, Error)]
9pub enum ErroContext7 {
10 #[error("No valid API key available after {tentativas} attempts")]
12 RetryEsgotado {
13 tentativas: u32,
15 },
16
17 #[error("All API keys failed due to authentication errors")]
19 SemChavesApi,
20
21 #[error("Invalid API response: status {status}")]
23 RespostaInvalida {
24 status: u16,
26 },
27
28 #[error("API returned error 400: {mensagem}")]
30 ApiRetornou400 {
31 mensagem: String,
33 },
34
35 #[error("Library not found: {library_id}")]
37 BibliotecaNaoEncontrada {
38 library_id: String,
40 },
41
42 #[error("")]
45 OperacaoKeysFalhou,
46}
47
48impl ErroContext7 {
49 pub fn exit_code(&self) -> i32 {
60 match self {
61 Self::RetryEsgotado { .. } => 69,
62 Self::SemChavesApi => 77,
63 Self::RespostaInvalida { .. } => 74,
64 Self::ApiRetornou400 { .. } => 65,
65 Self::BibliotecaNaoEncontrada { .. } => 66,
66 Self::OperacaoKeysFalhou => 1,
67 }
68 }
69}
70
71#[cfg(test)]
72mod testes {
73 use super::*;
74
75 #[test]
76 fn testa_erro_sem_chaves_api_display() {
77 let erro = ErroContext7::SemChavesApi;
78 let mensagem = erro.to_string();
79 assert!(
80 !mensagem.is_empty(),
81 "SemChavesApi deve ter mensagem não-vazia"
82 );
83 assert!(
84 mensagem.to_lowercase().contains("key")
85 || mensagem.to_lowercase().contains("api")
86 || mensagem.to_lowercase().contains("auth"),
87 "Mensagem deve mencionar key/api/auth, obteve: {mensagem}"
88 );
89 }
90
91 #[test]
92 fn testa_erro_retry_esgotado_contem_numero_de_tentativas() {
93 let erro = ErroContext7::RetryEsgotado { tentativas: 3 };
94 let mensagem = erro.to_string();
95 assert!(
96 mensagem.contains('3'),
97 "Mensagem deve conter número de tentativas (3), obteve: {mensagem}"
98 );
99 }
100
101 #[test]
102 fn testa_erro_resposta_invalida_contem_status() {
103 let erro = ErroContext7::RespostaInvalida { status: 500 };
104 let mensagem = erro.to_string();
105 assert!(
106 mensagem.contains("500"),
107 "Mensagem deve conter código de status, obteve: {mensagem}"
108 );
109 }
110
111 #[test]
112 fn testa_erro_api_400_contem_texto_do_erro() {
113 let erro = ErroContext7::ApiRetornou400 {
114 mensagem: "Parâmetro inválido".to_string(),
115 };
116 let mensagem = erro.to_string();
117 assert!(
118 mensagem.contains("Parâmetro inválido"),
119 "Mensagem deve conter texto do erro, obteve: {mensagem}"
120 );
121 }
122
123 #[test]
124 fn testa_resultado_alias_propaga_erro_context7() {
125 fn falha() -> Result<(), ErroContext7> {
126 Err(ErroContext7::SemChavesApi)
127 }
128 let resultado: Result<(), ErroContext7> = falha();
129 assert!(resultado.is_err(), "Resultado deve ser Err");
130 let err = resultado.unwrap_err();
131 assert!(matches!(err, ErroContext7::SemChavesApi));
132 }
133}