Listen to git commits for a specific repo and run a shell command

Add helpful error messages

vielle.dev bcbb66b8 46e72bb1

verified
+55 -18
+1
src/args.rs
··· 92 if val.contains("/") { 93 let entries: Vec<_> = val.split("/").collect(); 94 if entries.len() != 2 { 95 return Err(()); 96 } 97 handle = Some(entries[0][1..].to_string());
··· 92 if val.contains("/") { 93 let entries: Vec<_> = val.split("/").collect(); 94 if entries.len() != 2 { 95 + println!("Invalid argument: `{}` is malformed", val); 96 return Err(()); 97 } 98 handle = Some(entries[0][1..].to_string());
+52 -10
src/did.rs
··· 12 // create a txt resolver 13 let resolver = match Resolver::new(ResolverConfig::default(), ResolverOpts::default()) { 14 Ok(val) => val, 15 - Err(_) => return Err(()), 16 }; 17 18 // resolve _atproto.handle to a TXT record 19 let txt_res = match resolver.txt_lookup("_atproto.".to_owned() + &handle) { 20 Ok(val) => val, 21 - Err(_) => return Err(()), // collect all entries and convert to strings 22 } 23 .into_iter() 24 .map(|x| x.to_string()) ··· 32 // only 1 did= can exist 33 // https://atproto.com/specs/handle#:~:text=If%20multiple%20valid%20records%20with%20different%20DIDs%20are%20present,%20resolution%20should%20fail. 34 if did_res.len() != 1 { 35 return Err(()); 36 } 37 ··· 39 } 40 41 fn get_http_did(handle: &String) -> Result<String, ()> { 42 - println!(" Trying https for https://{}/.well-known/atproto-did", handle); 43 let res = 44 match reqwest::blocking::get("https://".to_owned() + handle + "/.well-known/atproto-did") { 45 Ok(val) => val, 46 - Err(_) => return Err(()), 47 }; 48 49 // as per spec, non 2xx code means failure 50 if !res.status().is_success() { 51 return Err(()); 52 } 53 54 let did_unparsed = match res.text() { 55 Ok(val) => val, 56 - Err(_) => return Err(()), 57 }; 58 59 let did = did_unparsed.trim(); 60 61 if !did.starts_with("did:") { 62 return Err(()); 63 }; 64 return Ok(String::from(did)); ··· 67 fn parse_doc(did: String, text: String) -> Result<DidDoc, ()> { 68 let text_json = match json::parse(&text) { 69 Ok(val) => val, 70 - Err(_) => return Err(()), 71 }; 72 73 for service in text_json["service"].members() { ··· 86 } 87 } 88 89 return Err(()); 90 } 91 92 fn get_plc_doc(plc: &str) -> Result<DidDoc, ()> { 93 let res = match reqwest::blocking::get("https://plc.directory/did:plc:".to_owned() + plc) { 94 Ok(val) => val, 95 - Err(_) => return Err(()), 96 }; 97 98 if !res.status().is_success() { 99 return Err(()); 100 } 101 ··· 103 "did:plc:".to_owned() + plc, 104 match res.text() { 105 Ok(val) => val, 106 - Err(_) => return Err(()), 107 }, 108 ); 109 } ··· 111 fn get_web_doc(web: &str) -> Result<DidDoc, ()> { 112 let res = match reqwest::blocking::get("https://".to_owned() + web + "/.well-known/did.json") { 113 Ok(val) => val, 114 - Err(_) => return Err(()), 115 }; 116 117 if !res.status().is_success() { 118 return Err(()); 119 } 120 ··· 122 "did:web:".to_owned() + web, 123 match res.text() { 124 Ok(val) => val, 125 - Err(_) => return Err(()), 126 }, 127 ); 128 } ··· 135 if let Ok(did) = get_http_did(&handle) { 136 did 137 } else { 138 return Err(()); 139 } 140 }; ··· 145 } else if did.starts_with("did:web:") { 146 get_web_doc(&did[8..]) 147 } else { 148 Err(()) 149 }; 150
··· 12 // create a txt resolver 13 let resolver = match Resolver::new(ResolverConfig::default(), ResolverOpts::default()) { 14 Ok(val) => val, 15 + Err(_) => { 16 + println!(" Couldn't create a DNS resolver"); 17 + return Err(()); 18 + } 19 }; 20 21 // resolve _atproto.handle to a TXT record 22 let txt_res = match resolver.txt_lookup("_atproto.".to_owned() + &handle) { 23 Ok(val) => val, 24 + Err(_) => { 25 + println!(" Couldn't resolve to a TXT record"); 26 + return Err(()); 27 + } // collect all entries and convert to strings 28 } 29 .into_iter() 30 .map(|x| x.to_string()) ··· 38 // only 1 did= can exist 39 // https://atproto.com/specs/handle#:~:text=If%20multiple%20valid%20records%20with%20different%20DIDs%20are%20present,%20resolution%20should%20fail. 40 if did_res.len() != 1 { 41 + println!(" Found too many DIDs for this handle"); 42 return Err(()); 43 } 44 ··· 46 } 47 48 fn get_http_did(handle: &String) -> Result<String, ()> { 49 + println!( 50 + " Trying https for https://{}/.well-known/atproto-did", 51 + handle 52 + ); 53 let res = 54 match reqwest::blocking::get("https://".to_owned() + handle + "/.well-known/atproto-did") { 55 Ok(val) => val, 56 + Err(_) => { 57 + println!(" GET request failed"); 58 + return Err(()); 59 + } 60 }; 61 62 // as per spec, non 2xx code means failure 63 if !res.status().is_success() { 64 + println!( 65 + " Got non 2xx status code: {}", 66 + res.status().as_str() 67 + ); 68 return Err(()); 69 } 70 71 let did_unparsed = match res.text() { 72 Ok(val) => val, 73 + Err(_) => { 74 + println!(" Missing or malformed body response"); 75 + return Err(()); 76 + } 77 }; 78 79 let did = did_unparsed.trim(); 80 81 if !did.starts_with("did:") { 82 + println!(" Did not find a DID"); 83 return Err(()); 84 }; 85 return Ok(String::from(did)); ··· 88 fn parse_doc(did: String, text: String) -> Result<DidDoc, ()> { 89 let text_json = match json::parse(&text) { 90 Ok(val) => val, 91 + Err(_) => { 92 + println!(" Malformed DID document"); 93 + return Err(()); 94 + } 95 }; 96 97 for service in text_json["service"].members() { ··· 110 } 111 } 112 113 + println!(" Missing fields from DID document"); 114 return Err(()); 115 } 116 117 fn get_plc_doc(plc: &str) -> Result<DidDoc, ()> { 118 let res = match reqwest::blocking::get("https://plc.directory/did:plc:".to_owned() + plc) { 119 Ok(val) => val, 120 + Err(_) => { 121 + println!(" GET request failed"); 122 + return Err(()); 123 + } 124 }; 125 126 if !res.status().is_success() { 127 + println!(" Got non 2xx status code: {}", res.status().as_str()); 128 + 129 return Err(()); 130 } 131 ··· 133 "did:plc:".to_owned() + plc, 134 match res.text() { 135 Ok(val) => val, 136 + Err(_) => { 137 + println!(" Missing or malformed body response"); 138 + return Err(()); 139 + } 140 }, 141 ); 142 } ··· 144 fn get_web_doc(web: &str) -> Result<DidDoc, ()> { 145 let res = match reqwest::blocking::get("https://".to_owned() + web + "/.well-known/did.json") { 146 Ok(val) => val, 147 + Err(_) => { 148 + println!(" GET request failed"); 149 + return Err(()); 150 + } 151 }; 152 153 if !res.status().is_success() { 154 + println!(" Got non 2xx status code: {}", res.status().as_str()); 155 return Err(()); 156 } 157 ··· 159 "did:web:".to_owned() + web, 160 match res.text() { 161 Ok(val) => val, 162 + Err(_) => { 163 + println!(" Missing or malformed body response"); 164 + return Err(()); 165 + } 166 }, 167 ); 168 } ··· 175 if let Ok(did) = get_http_did(&handle) { 176 did 177 } else { 178 + println!(" Could not get a DID"); 179 return Err(()); 180 } 181 }; ··· 186 } else if did.starts_with("did:web:") { 187 get_web_doc(&did[8..]) 188 } else { 189 + println!(" Could not get a DID document"); 190 Err(()) 191 }; 192
+2 -8
src/main.rs
··· 5 // load configuration 6 let config = match args::load_config() { 7 Ok(res) => res, 8 - Err(_) => { 9 - // q 10 - return Err(()); 11 - } 12 }; 13 14 // resolve handle to did 15 println!("Resolving {}", config.handle); 16 let did_doc = match did::get_did(config.handle) { 17 Ok(res) => res, 18 - Err(_) => { 19 - // q 20 - return Err(()); 21 - } 22 }; 23 // resolve did+repoName to knotserver 24
··· 5 // load configuration 6 let config = match args::load_config() { 7 Ok(res) => res, 8 + Err(_) => return Err(()), 9 }; 10 11 // resolve handle to did 12 println!("Resolving {}", config.handle); 13 let did_doc = match did::get_did(config.handle) { 14 Ok(res) => res, 15 + Err(_) => return Err(()), 16 }; 17 // resolve did+repoName to knotserver 18