Handle errors for Anilist, Lastfm, and Speedruncom Infos (#4)

Also make the client automatically request every 2 minutes an update for Last.fm
Also lightly change the `AnimateHeight` of `Info` (for the sake of the top border and better looks when multiple websites in one category)
This commit is contained in:
Taevas 2024-05-01 21:10:00 +02:00
parent dad037bed0
commit d9991ac0e7
5 changed files with 58 additions and 27 deletions

View file

@ -45,14 +45,6 @@ const handler: Handler = async () => {
}, },
}), }),
}); });
if (anilist.status !== 200) {
// log the issue in netlify, return 404 to the user anyway
console.log(await anilist.json());
return {
statusCode: 404,
body: "",
};
}
const json = (await anilist.json() as any).data.MediaList; const json = (await anilist.json() as any).data.MediaList;
const anime: AnilistInfo = { const anime: AnilistInfo = {

View file

@ -14,7 +14,7 @@ export default function Info({
}>; }>;
error?: boolean; error?: boolean;
}) { }) {
const [height, setHeight] = useState<Height>(0); const [height, setHeight] = useState<Height>(3);
const sections = websites.map((w, i) => { const sections = websites.map((w, i) => {
setTimeout(() => { // somehow necessary to not always rerender setTimeout(() => { // somehow necessary to not always rerender

View file

@ -17,18 +17,28 @@ export type AnilistInfo = {
export default function Anilist() { export default function Anilist() {
const [anilist, setAnilist]: [AnilistInfo, React.Dispatch<React.SetStateAction<AnilistInfo>>] = useState(); const [anilist, setAnilist]: [AnilistInfo, React.Dispatch<React.SetStateAction<AnilistInfo>>] = useState();
const [error, setError] = useState(false);
const getAnilist = async () => { const getAnilist = async () => {
const response = await fetch("/.netlify/functions/anilist").then(async r => r.json());
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
setAnilist(response); setAnilist(await fetch("/.netlify/functions/anilist").then(async r => r.json()));
}; };
useEffect(() => { useEffect(() => {
void getAnilist(); getAnilist().catch(() => {
setError(true);
});
}, []); }, []);
if (anilist === undefined) {
return <></>; if (!anilist) {
return (
<Info
type="Anime"
websites={[]}
error={error}
/>
);
} }
return ( return (

View file

@ -12,18 +12,39 @@ export type LastfmInfo = {
export default function Lastfm() { export default function Lastfm() {
const [lastfm, setLastfm]: [LastfmInfo, React.Dispatch<React.SetStateAction<LastfmInfo>>] = useState(); const [lastfm, setLastfm]: [LastfmInfo, React.Dispatch<React.SetStateAction<LastfmInfo>>] = useState();
const [error, setError] = useState(false);
const getLastfm = async () => { const getLastfm = async () => {
const response = await fetch("/.netlify/functions/lastfm").then(async r => r.json());
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
setLastfm(response); setLastfm(await fetch("/.netlify/functions/lastfm").then(async r => r.json()));
};
const updateLastFm = () => {
getLastfm().catch(() => {
setError(true);
});
}; };
useEffect(() => { useEffect(() => {
void getLastfm(); updateLastFm();
const timer = setInterval(() => {
updateLastFm();
}, 2 * 60 * 1000);
return () => {
clearInterval(timer);
};
}, []); }, []);
if (lastfm === undefined) {
return <></>; if (!lastfm) {
return (
<Info
type="Music"
websites={[]}
error={error}
/>
);
} }
return ( return (

View file

@ -12,21 +12,29 @@ export type SpeedruncomInfo = {
export default function Speedruncom() { export default function Speedruncom() {
const [speedruncom, setSpeedruncom]: [SpeedruncomInfo, React.Dispatch<React.SetStateAction<SpeedruncomInfo>>] = useState(); const [speedruncom, setSpeedruncom]: [SpeedruncomInfo, React.Dispatch<React.SetStateAction<SpeedruncomInfo>>] = useState();
const [error, setError] = useState(false);
const getSpeedruncom = async () => { const getSpeedruncom = async () => {
const response = await fetch("/.netlify/functions/speedruncom").then(async r => r.json());
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
setSpeedruncom(response); setSpeedruncom(await fetch("/.netlify/functions/speedruncom").then(async r => r.json()));
}; };
useEffect(() => { useEffect(() => {
void getSpeedruncom(); getSpeedruncom().catch(() => {
setError(true);
});
}, []); }, []);
if (speedruncom === undefined) {
return <></>;
}
const details = speedruncom.details.map((d, i) => <p key={`detail-${i}`}>{d}</p>); if (!speedruncom) {
return (
<Info
type="Speedrun"
websites={[]}
error={error}
/>
);
}
return ( return (
<Info <Info
@ -40,7 +48,7 @@ export default function Speedruncom() {
<div className="m-auto pl-2"> <div className="m-auto pl-2">
<p className="mb-2">Placed <strong>#{speedruncom.place}</strong> on:</p> <p className="mb-2">Placed <strong>#{speedruncom.place}</strong> on:</p>
<p className="font-bold">{speedruncom.game}</p> <p className="font-bold">{speedruncom.game}</p>
{details} {speedruncom.details.map((d, i) => <p key={`detail-${i}`}>{d}</p>)}
</div> </div>
</div>, </div>,
<p key={"date"} className="mt-2 font-bold">{speedruncom.date}</p>, <p key={"date"} className="mt-2 font-bold">{speedruncom.date}</p>,