A personal media tracker built on the AT Protocol opnshelf.xyz
at main 85 lines 2.1 kB view raw
1const SAFE_ONBOARDING_MESSAGES = new Set([ 2 "This watch was already imported.", 3 "We couldn't fetch details for this title right now.", 4 "We couldn't save this watch right now. Please try again.", 5 "We couldn't import this item.", 6 "Trakt user not found", 7 "Trakt profile is private or unavailable. Try CSV import instead.", 8 "Trakt rate limit reached. We will retry in the background shortly.", 9 "Trakt is temporarily unavailable. Please retry later or use CSV import.", 10]); 11 12const MAX_VISIBLE_IMPORT_ERRORS = 10; 13 14export function getSafeOnboardingErrorMessage( 15 error: unknown, 16 fallback: string, 17): string { 18 const message = getNestedStringMessage(error); 19 if (message && SAFE_ONBOARDING_MESSAGES.has(message)) { 20 return message; 21 } 22 23 return fallback; 24} 25 26export function getSafeImportErrorMessage(message: string): string { 27 return SAFE_ONBOARDING_MESSAGES.has(message) 28 ? message 29 : "We couldn't import this item."; 30} 31 32export function buildImportErrorList( 33 localMessages: string[], 34 serverMessages: string[], 35): string[] { 36 const uniqueMessages = Array.from( 37 new Set([ 38 ...localMessages, 39 ...serverMessages.map((message) => getSafeImportErrorMessage(message)), 40 ]), 41 ); 42 43 if (uniqueMessages.length <= MAX_VISIBLE_IMPORT_ERRORS) { 44 return uniqueMessages; 45 } 46 47 const remainingCount = uniqueMessages.length - MAX_VISIBLE_IMPORT_ERRORS; 48 return [ 49 ...uniqueMessages.slice(0, MAX_VISIBLE_IMPORT_ERRORS), 50 `...and ${remainingCount} more`, 51 ]; 52} 53 54function getNestedStringMessage(error: unknown): string | null { 55 if (typeof error === "string" && error.trim() !== "") { 56 return error; 57 } 58 59 if (!error || typeof error !== "object") { 60 return null; 61 } 62 63 if ("message" in error) { 64 const { message } = error as { message?: unknown }; 65 if (typeof message === "string" && message.trim() !== "") { 66 return message; 67 } 68 } 69 70 if ("body" in error) { 71 const nested = getNestedStringMessage((error as { body?: unknown }).body); 72 if (nested) { 73 return nested; 74 } 75 } 76 77 if ("error" in error) { 78 const nested = getNestedStringMessage((error as { error?: unknown }).error); 79 if (nested) { 80 return nested; 81 } 82 } 83 84 return null; 85}