aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-23 21:26:36 -0800
committerFuwn <[email protected]>2026-01-23 21:26:36 -0800
commite30cc3795166a372876969fd83b813472043b48b (patch)
treefc672e36c5d64a804963029a9fe8cc413fc4c220
parentfix(stores): Use unknown cast for dynamic property access (diff)
downloaddue.moe-e30cc3795166a372876969fd83b813472043b48b.tar.xz
due.moe-e30cc3795166a372876969fd83b813472043b48b.zip
fix: Add null guards and improve error messaging for user lookups
-rw-r--r--package.json3
-rw-r--r--pnpm-lock.yaml24
-rw-r--r--src/lib/Data/AniList/following.ts6
-rw-r--r--src/lib/Data/AniList/forum.ts6
-rw-r--r--src/lib/List/Manga/MangaListTemplate.svelte2
-rw-r--r--src/lib/Tools/BirthdaysTemplate.svelte2
-rw-r--r--src/lib/Tools/Tracker/Tool.svelte7
-rw-r--r--src/routes/user/[user]/+page.svelte4
-rw-r--r--src/routes/user/[user]/+page.ts2
-rw-r--r--src/routes/user/[user]/badges/+page.svelte25
-rw-r--r--src/routes/user/[user]/badges/+page.ts2
11 files changed, 51 insertions, 32 deletions
diff --git a/package.json b/package.json
index b789a2b1..7c996df9 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,6 @@
"@types/fast-levenshtein": "^0.0.4",
"@types/jsdom": "^21.1.6",
"@types/string-similarity": "^4.0.2",
- "@types/uuid": "^11.0.0",
"@types/web-push": "^3.6.3",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
@@ -62,7 +61,7 @@
"sortablejs": "^1.15.2",
"string-similarity": "^4.0.4",
"svelte-i18n": "^4.0.0",
- "uuid": "^10.0.0",
+ "uuid": "^13.0.0",
"wanakana": "^5.3.1",
"web-push": "^3.6.7"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 317c38d9..0269df13 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -59,8 +59,8 @@ importers:
specifier: ^4.0.0
version: 4.0.1([email protected])
uuid:
- specifier: ^10.0.0
- version: 10.0.0
+ specifier: ^13.0.0
+ version: 13.0.0
wanakana:
specifier: ^5.3.1
version: 5.3.1
@@ -89,9 +89,6 @@ importers:
'@types/string-similarity':
specifier: ^4.0.2
version: 4.0.2
- '@types/uuid':
- specifier: ^11.0.0
- version: 11.0.0
'@types/web-push':
specifier: ^3.6.3
version: 3.6.4
@@ -2596,13 +2593,6 @@ packages:
integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==
}
- '@types/[email protected]':
- resolution:
- {
- integrity: sha512-HVyk8nj2m+jcFRNazzqyVKiZezyhDKrGUA3jlEcg/nZ6Ms+qHwocba1Y/AaVaznJTAM9xpdFSh+ptbNrhOGvZA==
- }
- deprecated: This is a stub types definition. uuid provides its own type definitions, so you do not need this installed.
-
resolution:
{
@@ -6537,10 +6527,10 @@ packages:
integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
}
resolution:
{
- integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
+ integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==
}
hasBin: true
@@ -8559,10 +8549,6 @@ snapshots:
'@types/[email protected]': {}
- '@types/[email protected]':
- dependencies:
- uuid: 10.0.0
-
dependencies:
'@types/node': 25.0.10
@@ -11085,7 +11071,7 @@ snapshots:
diff --git a/src/lib/Data/AniList/following.ts b/src/lib/Data/AniList/following.ts
index b4772afa..bec1f53c 100644
--- a/src/lib/Data/AniList/following.ts
+++ b/src/lib/Data/AniList/following.ts
@@ -33,7 +33,11 @@ const followingPage = async (page: number, id: number): Promise<FollowingPage> =
export const followers = async (name: string): Promise<Partial<User>[]> => {
const activities = [];
let page = 1;
- const id = (await user(name)).id;
+ const userData = await user(name);
+
+ if (!userData) throw new Error(`User not found: ${name}`);
+
+ const id = userData.id;
let currentPage = await followingPage(page, id);
for (const activity of currentPage.data.Page.following) activities.push(activity);
diff --git a/src/lib/Data/AniList/forum.ts b/src/lib/Data/AniList/forum.ts
index b2467c9e..c8514fe1 100644
--- a/src/lib/Data/AniList/forum.ts
+++ b/src/lib/Data/AniList/forum.ts
@@ -47,7 +47,11 @@ const threadPage = async (page: number, userId: number): Promise<ThreadPage> =>
export const threads = async (username: string): Promise<Thread[]> => {
const allThreads = [];
- const userId = (await user(username)).id;
+ const userData = await user(username);
+
+ if (!userData) throw new Error(`User not found: ${username}`);
+
+ const userId = userData.id;
let page = 1;
let currentPage = await threadPage(page, userId);
diff --git a/src/lib/List/Manga/MangaListTemplate.svelte b/src/lib/List/Manga/MangaListTemplate.svelte
index 3fee9f6a..16665d56 100644
--- a/src/lib/List/Manga/MangaListTemplate.svelte
+++ b/src/lib/List/Manga/MangaListTemplate.svelte
@@ -61,7 +61,7 @@
`last${due ? '' : 'Completed'}MangaListLength`
)) as number | null;
- if (lastStoredList) lastListSize = parseInt(lastStoredList);
+ if (lastStoredList) lastListSize = parseInt(String(lastStoredList));
}
startTime = performance.now();
diff --git a/src/lib/Tools/BirthdaysTemplate.svelte b/src/lib/Tools/BirthdaysTemplate.svelte
index 951de5cf..daf4c5af 100644
--- a/src/lib/Tools/BirthdaysTemplate.svelte
+++ b/src/lib/Tools/BirthdaysTemplate.svelte
@@ -44,7 +44,7 @@
<Skeleton grid={true} count={100} width="150px" height="170px" />
{:then birthdays}
{@const todaysBirthdays = birthdays.filter(
- (birthday) => birthday.month === month && birthday.day === day
+ (birthday: { month: number; day: number }) => birthday.month === month && birthday.day === day
)}
<p>
diff --git a/src/lib/Tools/Tracker/Tool.svelte b/src/lib/Tools/Tracker/Tool.svelte
index 6c7fbf1c..a3705fbe 100644
--- a/src/lib/Tools/Tracker/Tool.svelte
+++ b/src/lib/Tools/Tracker/Tool.svelte
@@ -97,7 +97,12 @@
value={entry.progress}
size={3}
onchange={(e) =>
- adjustEntry(entry.id, e.target ? e.target.value || entry.progress : entry.progress)}
+ adjustEntry(
+ entry.id,
+ e.target
+ ? Number((e.target as HTMLInputElement).value) || entry.progress
+ : entry.progress
+ )}
/>
<span class="entry-adjust">
diff --git a/src/routes/user/[user]/+page.svelte b/src/routes/user/[user]/+page.svelte
index 7f33f170..eeeebf91 100644
--- a/src/routes/user/[user]/+page.svelte
+++ b/src/routes/user/[user]/+page.svelte
@@ -26,7 +26,9 @@
export let data;
$: ({ Profile } = data);
- $: preferences = $Profile.fetching ? undefined : ($Profile.data?.User.preferences as Preferences);
+ $: preferences = $Profile.fetching
+ ? undefined
+ : ($Profile.data?.User?.preferences as Preferences | undefined);
const setCategoriesQuery = graphql(`
mutation SetCategories($categories: [String!]!) {
diff --git a/src/routes/user/[user]/+page.ts b/src/routes/user/[user]/+page.ts
index e44f06aa..ca16077f 100644
--- a/src/routes/user/[user]/+page.ts
+++ b/src/routes/user/[user]/+page.ts
@@ -6,6 +6,8 @@ export const load = async (event: LoadEvent) => {
const username = event.params.user as string;
const userData = await user(username, /^\d+$/.test(username));
+ if (!userData) throw new Error(`User not found: ${username}`);
+
return {
...(await load_Profile({
event,
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index 2abf8377..69b74917 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -31,7 +31,7 @@
$: ({ BadgeWallUser } = data);
$: preferences = $BadgeWallUser.fetching
? undefined
- : ($BadgeWallUser.data?.User.preferences as Preferences);
+ : ($BadgeWallUser.data?.User?.preferences as Preferences | undefined);
$: if (browser && preferences && preferences.badge_wall_css) {
const sanitise = (css: string) =>
@@ -191,7 +191,7 @@
let importLinks = false;
let importCategory = '';
let importReplies = false;
- let badger: Partial<User>;
+ let badger: Partial<User> | null;
let migrateMode = false;
let hideMode = false;
const authorised = authorisedJson.includes($identity.id);
@@ -202,10 +202,17 @@
type GroupedBadges = { [key: string]: IndexedBadge[] };
- const setShadowHide = () =>
+ const setShadowHide = () => {
+ if (!badger) {
+ loadError = 'Something went wrong. Try refreshing.';
+
+ return;
+ }
+
shadowHideBadgeQuery.mutate({
id: badger.id as number
});
+ };
onMount(async () => {
if (browser && (await localforage.getItem('badgeWallNoticeDismissed'))) noticeDismissed = true;
@@ -217,8 +224,8 @@
}
: await user(data.username);
- if (!isId && !badger) {
- loadError = 'User not found.';
+ if (!badger) {
+ loadError = "Couldn't find this user.";
return;
}
@@ -506,6 +513,12 @@
const shadowHideBadge = () => {
if (!selectedBadge && !authorised) return;
+ if (!badger) {
+ loadError = 'Something went wrong. Try refreshing.';
+
+ return;
+ }
+
shadowHideBadgeQuery
.mutate({
id: badger.id as number,
@@ -528,6 +541,8 @@
<Message message="Loading badges ..." />
<Skeleton grid={true} count={100} width="150px" height="170px" />
+ {:else if !$BadgeWallUser.data.User}
+ <Message message="No badges yet." />
{:else}
{@const ungroupedBadges = castBadgesToIndexedBadges($BadgeWallUser.data.User.badges)}
{@const isBadgeSelected =
diff --git a/src/routes/user/[user]/badges/+page.ts b/src/routes/user/[user]/badges/+page.ts
index bd13fdc4..db70d16c 100644
--- a/src/routes/user/[user]/badges/+page.ts
+++ b/src/routes/user/[user]/badges/+page.ts
@@ -6,6 +6,8 @@ export const load = async (event: LoadEvent) => {
const username = event.params.user as string;
const userData = await user(username, /^\d+$/.test(username));
+ if (!userData) throw new Error(`User not found: ${username}`);
+
return {
...(await load_BadgeWallUser({
event,