Skip to content

Commit c6505dd

Browse files
committed
fix: add safe JSON parsing utility to handle profile content
1 parent 7576ed0 commit c6505dd

1 file changed

Lines changed: 61 additions & 29 deletions

File tree

utils/nostr/fetch-service.ts

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,23 @@ function isHexString(value: string): boolean {
4545
return /^[0-9a-fA-F]{64}$/.test(value);
4646
}
4747

48+
function parseJsonSafely<T>(input: unknown): T | null {
49+
if (typeof input !== "string") {
50+
return null;
51+
}
52+
53+
const trimmed = input.trim();
54+
if (!trimmed) {
55+
return null;
56+
}
57+
58+
try {
59+
return JSON.parse(trimmed) as T;
60+
} catch {
61+
return null;
62+
}
63+
}
64+
4865
export const fetchAllPosts = async (
4966
nostr: NostrManager,
5067
relays: string[],
@@ -443,20 +460,28 @@ export const fetchProfile = async (
443460
}
444461

445462
for (const [pubkey, event] of latestDbEvents.entries()) {
446-
try {
447-
const content = JSON.parse(event.content);
448-
const profile: NipProfile = {
449-
pubkey: event.pubkey,
450-
created_at: event.created_at,
451-
content,
452-
nip05Verified: false,
453-
};
454-
dbProfileMap.set(pubkey, profile);
455-
updateProfileIfNewer(profile);
456-
} catch (error) {
457-
console.error(
458-
`Failed to parse profile from DB: ${pubkey}`,
459-
error
463+
const content = parseJsonSafely<Record<string, any>>(
464+
event.content
465+
);
466+
if (!content) {
467+
console.warn(
468+
`Skipping invalid profile JSON from DB: ${pubkey}`
469+
);
470+
continue;
471+
}
472+
473+
const profile: NipProfile = {
474+
pubkey: event.pubkey,
475+
created_at: event.created_at,
476+
content,
477+
nip05Verified: false,
478+
};
479+
dbProfileMap.set(pubkey, profile);
480+
updateProfileIfNewer(profile);
481+
if (content.nip05) {
482+
profile.nip05Verified = await verifyNip05Identifier(
483+
content.nip05,
484+
event.pubkey
460485
);
461486
}
462487
}
@@ -494,23 +519,30 @@ export const fetchProfile = async (
494519
!existing ||
495520
event.created_at > existing.created_at
496521
) {
497-
try {
498-
const content = JSON.parse(event.content);
499-
const profile: NipProfile = {
500-
pubkey: event.pubkey,
501-
created_at: event.created_at,
502-
content,
503-
nip05Verified: false,
504-
};
505-
profileMap.set(event.pubkey, profile);
506-
updatedProfiles.set(event.pubkey, profile);
507-
updateProfileIfNewer(profile);
508-
} catch (error) {
509-
console.error(
510-
`Failed parse profile for pubkey: ${event.pubkey}, ${event.content}`,
511-
error
522+
const content = parseJsonSafely<Record<string, any>>(event.content);
523+
if (!content) {
524+
console.warn(
525+
`Skipping invalid profile JSON for pubkey: ${event.pubkey}`
526+
);
527+
continue;
528+
}
529+
530+
const profile: NipProfile = {
531+
pubkey: event.pubkey,
532+
created_at: event.created_at,
533+
content,
534+
nip05Verified: false,
535+
};
536+
if (content.nip05) {
537+
profile.nip05Verified = await verifyNip05Identifier(
538+
content.nip05,
539+
event.pubkey
512540
);
513541
}
542+
543+
profileMap.set(event.pubkey, profile);
544+
updatedProfiles.set(event.pubkey, profile);
545+
updateProfileIfNewer(profile);
514546
}
515547
}
516548

0 commit comments

Comments
 (0)