this repo has no description

Error handling for list customization

+15 -6
+15 -6
public/main.tsx
··· 33 33 function parseKinks(kinkStr: string) { 34 34 const kinkCode = kinkStr 35 35 .split("\n") 36 - .map((e) => e.trim()) 37 - .filter((e) => e); 36 + .map((e, i) => [e.trim(), i + 1] as const) 37 + .filter((e) => e[0]); 38 38 39 39 const kinkCategories: KinkCategory[] = []; 40 40 ··· 42 42 43 43 let curKinkCategory: KinkCategory | undefined; 44 44 let curKinkId = 0; 45 - for (const line of kinkCode) { 45 + for (const [line, lineNum] of kinkCode) { 46 46 if (line.startsWith("#")) { 47 47 const [categoryName, categoryDesc] = sliceOnce(removeSymbols(line, "#"), ":::"); 48 48 ··· 55 55 kinkCategories.push(curKinkCategory); 56 56 } else if (line.startsWith("(") && line.endsWith(")")) { 57 57 if (curKinkCategory === undefined) { 58 - throw new Error("Encountered a participant definition before a kink type declaration"); 58 + throw new Error(`Encountered a participant definition before a kink type declaration (line ${lineNum})`); 59 59 } 60 60 curKinkCategory.participants = removeSymbols(line, "(", ")") 61 61 .split(",") 62 62 .map((e) => e.trim()); 63 63 } else if (line.startsWith("*")) { 64 64 if (curKinkCategory?.kinks === undefined) { 65 - throw new Error("Encountered a kink definition before a kink type declaration"); 65 + throw new Error(`Encountered a kink definition before a kink type declaration (line ${lineNum})`); 66 66 } 67 67 68 68 const [kinkName, kinkDescription] = sliceOnce(removeSymbols(line, "*"), ":::"); ··· 1071 1071 onClose: () => void; 1072 1072 }) { 1073 1073 const [localKinkText, setLocalKinkText] = useState(kinkText.value); 1074 + const error = useMemo(() => { 1075 + try { 1076 + parseKinks(localKinkText); 1077 + return undefined; 1078 + } catch (err) { 1079 + return err; 1080 + } 1081 + }, [localKinkText]); 1074 1082 1075 1083 function save() { 1076 1084 localStorage.setItem("kink-text", localKinkText); ··· 1100 1108 setLocalKinkText(e.currentTarget.value); 1101 1109 }} style={{'--bulma-textarea-min-height': '24em'}} /> 1102 1110 </div> 1111 + {error && <div class="notification is-danger">{String(error)}</div>} 1103 1112 1104 1113 <div class="field is-grouped"> 1105 - <button class="button is-primary" onClick={save}>Save</button> 1114 + <button class="button is-primary" disabled={error !== undefined} onClick={save}>Save</button> 1106 1115 <button class="button is-secondary" onClick={resetToDefault}>Reset to Default</button> 1107 1116 </div> 1108 1117 {/* {user.value && <button class="button is-primary" onClick={publish}>Publish to ATProto</button>} */}