@@ -69,7 +69,7 @@ fn prepare_client_and_headers(
69
69
headers. insert (
70
70
AUTHORIZATION ,
71
71
HeaderValue :: from_str ( & format ! ( "Bearer {}" , bearer_token) )
72
- . map_err ( |err | CliError :: StatusErr ( err . to_string ( ) ) ) ?,
72
+ . map_err ( |_ | CliError :: GetEnvVar ( "LINKUP_CF_API_TOKEN" . to_string ( ) ) ) ?,
73
73
) ;
74
74
75
75
Ok ( ( client, headers) )
@@ -86,7 +86,12 @@ fn send_request<T: for<'de> serde::Deserialize<'de>>(
86
86
let builder = match method {
87
87
"GET" => client. get ( url) ,
88
88
"POST" => client. post ( url) ,
89
- _ => return Err ( CliError :: StatusErr ( "Unsupported HTTP method" . to_string ( ) ) ) ,
89
+ _ => {
90
+ return Err ( CliError :: HttpErr ( format ! (
91
+ "Unsupported HTTP method: {}" ,
92
+ method
93
+ ) ) )
94
+ }
90
95
} ;
91
96
92
97
let builder = builder. headers ( headers) ;
@@ -96,25 +101,18 @@ fn send_request<T: for<'de> serde::Deserialize<'de>>(
96
101
builder
97
102
} ;
98
103
99
- let response = builder. send ( ) . map_err ( |err| {
100
- CliError :: StatusErr ( format ! ( "Failed to send request, {}" , err ) . to_string ( ) )
101
- } ) ?;
104
+ let response = builder
105
+ . send ( )
106
+ . map_err ( |err| CliError :: HttpErr ( format ! ( "Failed to send request, {}" , err ) . to_string ( ) ) ) ?;
102
107
103
108
if response. status ( ) . is_success ( ) {
104
109
let response_body = response. text ( ) . map_err ( |err| {
105
- CliError :: StatusErr ( format ! ( "Could not read response body, {}" , err) . to_string ( ) )
110
+ CliError :: HttpErr ( format ! ( "Could not read response body, {}" , err) . to_string ( ) )
106
111
} ) ?;
107
- serde_json:: from_str ( & response_body) . map_err ( |err| {
108
- CliError :: StatusErr (
109
- format ! (
110
- "Could not parse JSON, {}. Response body: {}" ,
111
- err, response_body
112
- )
113
- . to_string ( ) ,
114
- )
115
- } )
112
+ serde_json:: from_str ( & response_body)
113
+ . map_err ( |err| CliError :: ParseErr ( "from str to JSON" . to_string ( ) , err. to_string ( ) ) )
116
114
} else {
117
- Err ( CliError :: StatusErr ( format ! (
115
+ Err ( CliError :: HttpErr ( format ! (
118
116
"Failed to get a successful response: {}" ,
119
117
response. status( )
120
118
) ) )
@@ -133,7 +131,7 @@ pub struct RealPaidTunnelManager;
133
131
impl PaidTunnelManager for RealPaidTunnelManager {
134
132
fn get_tunnel_id ( & self , tunnel_name : & str ) -> Result < Option < String > , CliError > {
135
133
let account_id = env:: var ( "LINKUP_CLOUDFLARE_ACCOUNT_ID" )
136
- . map_err ( |err | CliError :: BadConfig ( err . to_string ( ) ) ) ?;
134
+ . map_err ( |_ | CliError :: GetEnvVar ( "LINKUP_CLOUDFLARE_ACCOUNT_ID" . to_string ( ) ) ) ?;
137
135
let url = format ! (
138
136
"https://api.cloudflare.com/client/v4/accounts/{}/cfd_tunnel" ,
139
137
account_id
@@ -160,7 +158,7 @@ impl PaidTunnelManager for RealPaidTunnelManager {
160
158
fn create_tunnel ( & self , tunnel_name : & str ) -> Result < String , CliError > {
161
159
let tunnel_secret = generate_tunnel_secret ( ) ;
162
160
let account_id = env:: var ( "LINKUP_CLOUDFLARE_ACCOUNT_ID" )
163
- . map_err ( |err | CliError :: BadConfig ( err . to_string ( ) ) ) ?;
161
+ . map_err ( |_ | CliError :: GetEnvVar ( "LINKUP_CLOUDFLARE_ACCOUNT_ID" . to_string ( ) ) ) ?;
164
162
let url = format ! (
165
163
"https://api.cloudflare.com/client/v4/accounts/{}/cfd_tunnel" ,
166
164
account_id,
@@ -170,21 +168,26 @@ impl PaidTunnelManager for RealPaidTunnelManager {
170
168
name : tunnel_name. to_string ( ) ,
171
169
tunnel_secret : tunnel_secret. clone ( ) ,
172
170
} )
173
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
171
+ . map_err ( |err| CliError :: ParseErr ( "from JSON to String" . to_string ( ) , err. to_string ( ) ) ) ?;
174
172
175
173
let parsed: CreateTunnelResponse =
176
174
send_request ( & client, & url, headers, Some ( body) , "POST" ) ?;
177
- save_tunnel_credentials ( & RealSystem , & parsed. result . id , & tunnel_secret)
178
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
179
- create_config_yml ( & RealSystem , & parsed. result . id )
180
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
175
+ save_tunnel_credentials ( & RealSystem , & parsed. result . id , & tunnel_secret) . map_err ( |err| {
176
+ CliError :: FileErr (
177
+ "Failed to save tunnel credentials" . to_string ( ) ,
178
+ err. to_string ( ) ,
179
+ )
180
+ } ) ?;
181
+ create_config_yml ( & RealSystem , & parsed. result . id ) . map_err ( |err| {
182
+ CliError :: FileErr ( "Failed to create config YML" . to_string ( ) , err. to_string ( ) )
183
+ } ) ?;
181
184
182
185
Ok ( parsed. result . id )
183
186
}
184
187
185
188
fn create_dns_record ( & self , tunnel_id : & str , tunnel_name : & str ) -> Result < ( ) , CliError > {
186
189
let zone_id = env:: var ( "LINKUP_CLOUDFLARE_ZONE_ID" )
187
- . map_err ( |err | CliError :: BadConfig ( err . to_string ( ) ) ) ?;
190
+ . map_err ( |_ | CliError :: GetEnvVar ( "LINKUP_CLOUDFLARE_ZONE_ID" . to_string ( ) ) ) ?;
188
191
let url = format ! (
189
192
"https://api.cloudflare.com/client/v4/zones/{}/dns_records" ,
190
193
zone_id
@@ -196,7 +199,7 @@ impl PaidTunnelManager for RealPaidTunnelManager {
196
199
r#type : "CNAME" . to_string ( ) ,
197
200
proxied : true ,
198
201
} )
199
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
202
+ . map_err ( |err| CliError :: ParseErr ( "from JSON to String" . to_string ( ) , err. to_string ( ) ) ) ?;
200
203
201
204
let _parsed: CreateDNSRecordResponse =
202
205
send_request ( & client, & url, headers, Some ( body) , "POST" ) ?;
@@ -217,7 +220,7 @@ fn save_tunnel_credentials(
217
220
) -> Result < ( ) , CliError > {
218
221
let account_id = sys
219
222
. get_env ( "LINKUP_CLOUDFLARE_ACCOUNT_ID" )
220
- . map_err ( |err | CliError :: BadConfig ( err . to_string ( ) ) ) ?;
223
+ . map_err ( |_ | CliError :: GetEnvVar ( "LINKUP_CLOUDFLARE_ACCOUNT_ID" . to_string ( ) ) ) ?;
221
224
let data = serde_json:: json!( {
222
225
"AccountTag" : account_id,
223
226
"TunnelID" : tunnel_id,
@@ -227,12 +230,14 @@ fn save_tunnel_credentials(
227
230
// Determine the directory path
228
231
let home_dir = sys
229
232
. get_env ( "HOME" )
230
- . map_err ( |err | CliError :: BadConfig ( err . to_string ( ) ) ) ?;
233
+ . map_err ( |_ | CliError :: GetEnvVar ( "HOME" . to_string ( ) ) ) ?;
231
234
let dir_path = Path :: new ( & home_dir) . join ( ".cloudflared" ) ;
232
235
233
236
// Create the directory if it does not exist
234
237
if !dir_path. exists ( ) {
235
- fs:: create_dir_all ( & dir_path) . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
238
+ fs:: create_dir_all ( & dir_path) . map_err ( |err| {
239
+ CliError :: FileErr ( "Could not create directory" . to_string ( ) , err. to_string ( ) )
240
+ } ) ?
236
241
}
237
242
238
243
// Define the file path
@@ -241,10 +246,10 @@ fn save_tunnel_credentials(
241
246
// Create and write to the file
242
247
let mut file: Box < dyn FileLike > = sys
243
248
. create_file ( file_path)
244
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
249
+ . map_err ( |err| CliError :: FileErr ( "Could not create file" . to_string ( ) , err. to_string ( ) ) ) ?;
245
250
let data_string = data. to_string ( ) ;
246
251
sys. write_file ( & mut file, & data_string)
247
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
252
+ . map_err ( |err| CliError :: FileErr ( "Could not write to file" . to_string ( ) , err. to_string ( ) ) ) ?;
248
253
249
254
Ok ( ( ) )
250
255
}
@@ -253,14 +258,15 @@ fn create_config_yml(sys: &dyn System, tunnel_id: &str) -> Result<(), CliError>
253
258
// Determine the directory path
254
259
let home_dir = sys
255
260
. get_env ( "HOME" )
256
- . map_err ( |err | CliError :: BadConfig ( err . to_string ( ) ) ) ?;
261
+ . map_err ( |_ | CliError :: GetEnvVar ( "HOME" . to_string ( ) ) ) ?;
257
262
let dir_path = Path :: new ( & home_dir) . join ( ".cloudflared" ) ;
258
263
259
264
// Create the directory if it does not exist
260
265
if !sys. file_exists ( dir_path. as_path ( ) ) {
261
266
log:: info!( "Creating directory: {:?}" , dir_path) ;
262
- sys. create_dir_all ( & dir_path)
263
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
267
+ sys. create_dir_all ( & dir_path) . map_err ( |err| {
268
+ CliError :: FileErr ( "Could not create directory" . to_string ( ) , err. to_string ( ) )
269
+ } ) ?;
264
270
}
265
271
266
272
// Define the file path
@@ -277,9 +283,9 @@ fn create_config_yml(sys: &dyn System, tunnel_id: &str) -> Result<(), CliError>
277
283
278
284
let mut file: Box < dyn FileLike > = sys
279
285
. create_file ( dir_path. join ( "config.yml" ) )
280
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
286
+ . map_err ( |err| CliError :: FileErr ( "Could not create file" . to_string ( ) , err. to_string ( ) ) ) ?;
281
287
sys. write_file ( & mut file, & serialized)
282
- . map_err ( |err| CliError :: StatusErr ( err. to_string ( ) ) ) ?;
288
+ . map_err ( |err| CliError :: FileErr ( "Could not write to file" . to_string ( ) , err. to_string ( ) ) ) ?;
283
289
Ok ( ( ) )
284
290
}
285
291
0 commit comments