mirror of
https://github.com/hoornet/vega.git
synced 2026-07-11 02:58:13 -07:00
Fix React error #31 crash from malformed Nostr profiles
Malformed profiles with non-string fields (e.g. nip05: {}) crashed
React's entire render tree in production. Add typeof guards and
profileName() utility across all components that render profile data.
Add ErrorBoundary in main.tsx to show crash details instead of blank screen.
This commit is contained in:
@@ -7,14 +7,15 @@ import { Nip05Field } from "./Nip05Field";
|
||||
|
||||
export function EditProfileForm({ pubkey, onSaved }: { pubkey: string; onSaved: () => void }) {
|
||||
const { profile, fetchOwnProfile } = useUserStore();
|
||||
const [name, setName] = useState(profile?.name || "");
|
||||
const [displayName, setDisplayName] = useState(profile?.displayName || "");
|
||||
const [about, setAbout] = useState(profile?.about || "");
|
||||
const [picture, setPicture] = useState(profile?.picture || "");
|
||||
const [banner, setBanner] = useState(profile?.banner || "");
|
||||
const [website, setWebsite] = useState(profile?.website || "");
|
||||
const [nip05, setNip05] = useState(profile?.nip05 || "");
|
||||
const [lud16, setLud16] = useState(profile?.lud16 || "");
|
||||
const safeStr = (v: unknown) => (typeof v === "string" ? v : "");
|
||||
const [name, setName] = useState(safeStr(profile?.name));
|
||||
const [displayName, setDisplayName] = useState(safeStr(profile?.displayName));
|
||||
const [about, setAbout] = useState(safeStr(profile?.about));
|
||||
const [picture, setPicture] = useState(safeStr(profile?.picture));
|
||||
const [banner, setBanner] = useState(safeStr(profile?.banner));
|
||||
const [website, setWebsite] = useState(safeStr(profile?.website));
|
||||
const [nip05, setNip05] = useState(safeStr(profile?.nip05));
|
||||
const [lud16, setLud16] = useState(safeStr(profile?.lud16));
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [saved, setSaved] = useState(false);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useMuteStore } from "../../stores/mute";
|
||||
import { useProfile } from "../../hooks/useProfile";
|
||||
import { useReputation } from "../../hooks/useReputation";
|
||||
import { fetchUserNotesNIP65, fetchAuthorArticles, getNDK } from "../../lib/nostr";
|
||||
import { shortenPubkey } from "../../lib/utils";
|
||||
import { shortenPubkey, profileName } from "../../lib/utils";
|
||||
import { NoteCard } from "../feed/NoteCard";
|
||||
import { ArticleCard } from "../article/ArticleCard";
|
||||
import { ZapModal } from "../zap/ZapModal";
|
||||
@@ -17,7 +17,7 @@ import { ProfileMediaGallery } from "./ProfileMediaGallery";
|
||||
function TopFollowerAvatar({ pubkey }: { pubkey: string }) {
|
||||
const profile = useProfile(pubkey);
|
||||
const { openProfile } = useUIStore();
|
||||
const name = profile?.displayName || profile?.name || pubkey.slice(0, 8) + "…";
|
||||
const name = profileName(profile, pubkey.slice(0, 8) + "…");
|
||||
|
||||
return (
|
||||
<button
|
||||
@@ -85,12 +85,12 @@ export function ProfileView() {
|
||||
}
|
||||
};
|
||||
|
||||
const name = profile?.displayName || profile?.name || shortenPubkey(pubkey);
|
||||
const avatar = profile?.picture;
|
||||
const about = profile?.about;
|
||||
const nip05 = profile?.nip05;
|
||||
const website = profile?.website;
|
||||
const lud16 = profile?.lud16;
|
||||
const name = profileName(profile, shortenPubkey(pubkey));
|
||||
const avatar = typeof profile?.picture === "string" ? profile.picture : undefined;
|
||||
const about = typeof profile?.about === "string" ? profile.about : undefined;
|
||||
const nip05 = typeof profile?.nip05 === "string" ? profile.nip05 : undefined;
|
||||
const website = typeof profile?.website === "string" ? profile.website : undefined;
|
||||
const lud16 = typeof profile?.lud16 === "string" ? profile.lud16 : undefined;
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
Reference in New Issue
Block a user