(row)
| 242 | } |
| 243 | |
| 244 | function classify(row) { |
| 245 | const orig = safeUrl(row.original_url); |
| 246 | const fin = safeUrl(row.resolved_url); |
| 247 | const status = row.status_code; |
| 248 | const expl = row.explanation; |
| 249 | |
| 250 | if (!orig) return { class: CLASS.UNKNOWN, reason: 'malformed original URL' }; |
| 251 | |
| 252 | if (fin && isParked(fin.href)) { |
| 253 | return { class: CLASS.PARKED, reason: `final URL on parked host: ${fin.hostname}` }; |
| 254 | } |
| 255 | |
| 256 | if (status === 'DNS' || /DNS lookup failed/i.test(expl)) { |
| 257 | return { class: CLASS.DEAD_DNS, reason: 'host does not resolve in DNS' }; |
| 258 | } |
| 259 | |
| 260 | if (status === '404' || /Not found/i.test(expl)) { |
| 261 | return { class: CLASS.NOT_FOUND, reason: '404' }; |
| 262 | } |
| 263 | |
| 264 | if (status === '403' || status === '429' || status === '999' || status === '525' || status === '522' || /Forbidden|HTTP 999|HTTP 5/.test(expl) || /Connection failed/i.test(expl)) { |
| 265 | return { class: CLASS.THROTTLED, reason: `${status} ${expl}` }; |
| 266 | } |
| 267 | |
| 268 | if (status === '200' || /Redirects to final URL/i.test(expl)) { |
| 269 | if (!fin || row.original_url === row.resolved_url) return { class: CLASS.OK, reason: '' }; |
| 270 | return classifyRedirect(orig, fin); |
| 271 | } |
| 272 | |
| 273 | return { class: CLASS.UNKNOWN, reason: `${status} ${expl}` }; |
| 274 | } |
| 275 | |
| 276 | function classifyRedirect(orig, fin) { |
| 277 | // Strip ALL query params before comparing — redirect-added params are almost |
no test coverage detected