A small web tool for showing what Bluesky moderation labels are assigned to a profile

more friendly error messages

Changed files
+37 -5
+37 -5
scanner.js
··· 6 6 'deer.social', 7 7 ]; 8 8 9 + class URLError extends Error {} 10 + 9 11 document.addEventListener("DOMContentLoaded", function() { 10 12 initScanner(); 11 13 }); ··· 56 58 } else if (query.match(/^did\:\w+\:/)) { 57 59 doScan = scanAccount(query); 58 60 } else { 59 - resultField.innerText = 'Enter a user handle or a post URL.'; 61 + resultField.innerText = '🤨 Enter a user handle or a post URL.'; 60 62 foundLabels.innerHTML = ''; 61 63 return; 62 64 } ··· 78 80 } 79 81 }) 80 82 .catch((error) => { 81 - resultField.innerText = error; 83 + displayError(error); 82 84 }) 83 85 .finally(() => { 84 - this.search.disabled = false; 86 + this.search.disabled = false; 85 87 }); 86 88 }); 87 89 } 88 90 91 + function displayError(error) { 92 + if (error instanceof APIError) { 93 + if (error.code == 400) { 94 + if (error.json.error == 'AccountTakedown') { 95 + resultField.innerText = '🚫 Account was taken down'; 96 + return; 97 + } else if (error.json.error == 'InvalidRequest') { 98 + if (error.json.message == 'Profile not found') { 99 + resultField.innerText = '🚫 Account not found'; 100 + return; 101 + } else if (error.json.message == 'Unable to resolve handle') { 102 + resultField.innerText = '👾 Unable to resolve handle'; 103 + return; 104 + } 105 + } else if (error.json.error == 'AccountDeactivated') { 106 + resultField.innerText = '😶‍🌫️ Account is deactivated'; 107 + return; 108 + } 109 + } 110 + 111 + resultField.innerText = error; 112 + return; 113 + } else if (error instanceof URLError) { 114 + resultField.innerText = `⚠️ ${error.message}`; 115 + return; 116 + } 117 + 118 + resultField.innerText = `${error.constructor.name}: ${error.message}`; 119 + } 120 + 89 121 async function scanHandle(handle) { 90 122 let json = await appView.getRequest('com.atproto.identity.resolveHandle', { handle }); 91 123 let userDID = json.did; ··· 116 148 let url = new URL(string); 117 149 118 150 if (url.protocol != 'https:') { 119 - throw 'URL must start with https://'; 151 + throw new URLError('URL must start with https://'); 120 152 } 121 153 122 154 if (!acceptedHostnames.includes(url.host)) { ··· 140 172 let json = await appView.getRequest('com.atproto.identity.resolveHandle', { handle: match[1] }); 141 173 atURI = `at://${json.did}/app.bsky.feed.post/${match[2]}`; 142 174 } else { 143 - throw 'Invalid URL'; 175 + throw new URLError('Unknown URL'); 144 176 } 145 177 } 146 178 }