Move setting response status to a utility function

This commit is contained in:
Maciej Pędzich 2023-01-08 13:40:32 +01:00
parent 05e28ddbc1
commit 7d4e1e59ce
3 changed files with 67 additions and 52 deletions

View File

@ -1,64 +1,24 @@
---
import BaseLayout from './BaseLayout.astro';
import { decode } from 'html-entities';
import type { PlaylistSnapshot } from '../models/playlist-snapshot';
const { playlistId } = Astro.params;
let playlist: PlaylistSnapshot | null = null;
let playlistFetchError = '';
let displayTitle = '';
let description = '';
try {
const githubResponse = await fetch(
`https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/main/playlists/pretty/${playlistId}.json`
);
if (!githubResponse.ok) {
const errorMessage = githubResponse.status === 404
? "This playlist doesn't exist"
: "Failed to fetch playlist's data";
Astro.response.status = githubResponse.status;
Astro.response.statusText = errorMessage;
throw new Error(errorMessage);
}
playlist = (await githubResponse.json()) as PlaylistSnapshot;
description = decode(playlist.description, { level: 'html5' });
displayTitle = playlist.unique_name !== playlist.original_name
? `${playlist.unique_name} (${playlist.original_name})`
: playlist.original_name;
} catch (error) {
console.error(error);
const expectedErrorMessages = [
"Failed to fetch playlist's data",
"This playlist doesn't exist"
];
const [miscError] = expectedErrorMessages
displayTitle = 'Error';
playlistFetchError = (error as Error).message;
description = expectedErrorMessages.includes(playlistFetchError)
? playlistFetchError
: miscError;
interface Props {
playlist: PlaylistSnapshot | null;
title: string;
description: string;
}
const { playlist, title, description } = Astro.props as Props;
---
<BaseLayout title={displayTitle} description={description}>
<BaseLayout title={title} description={description}>
<div class="mt-24 text-center flex flex-col gap-5 items-center">
{
playlist ? (
<h1 class="font-bold text-4xl">
<a href={playlist.url} target="_blank" rel="noopener noreferrer">
{displayTitle}
{title}
</a>
by
<a
@ -86,9 +46,9 @@ try {
</div>
<slot />
) : (
<div class="alert alert-error max-w-md justify-center shadow-lg">
{description}
</div>
<div class="alert alert-error max-w-md justify-center shadow-lg">
<span>{description}</span>
</div>
)
}
</div>

View File

@ -1,7 +1,10 @@
---
import PlaylistPageSection from '../../../layouts/PlaylistPageSection.astro';
import { getPlaylistLayoutProps } from '../../../utils/getPlaylistLayoutProps';
const layoutProps = await getPlaylistLayoutProps.call(Astro);
---
<PlaylistPageSection>
<PlaylistPageSection {...layoutProps}>
<p class="text-lg">TODO: Implement snapshot calendar</p>
</PlaylistPageSection>

View File

@ -0,0 +1,52 @@
import { decode } from 'html-entities';
import type { AstroGlobal } from 'astro';
import type { PlaylistSnapshot } from '../models/playlist-snapshot';
export async function getPlaylistLayoutProps(this: Readonly<AstroGlobal>) {
const { playlistId } = this.params;
let playlist: PlaylistSnapshot | null = null;
let title = '';
let description = '';
try {
const githubResponse = await fetch(
`https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/main/playlists/pretty/${playlistId}.json`
);
if (!githubResponse.ok) {
const errorMessage =
githubResponse.status === 404
? "This playlist doesn't exist"
: "Failed to fetch playlist's data";
throw new Error(errorMessage);
}
playlist = (await githubResponse.json()) as PlaylistSnapshot;
description = decode(playlist.description, { level: 'html5' });
title =
playlist.unique_name !== playlist.original_name
? `${playlist.unique_name} (${playlist.original_name})`
: playlist.original_name;
} catch (e) {
const expectedErrorMessages = [
"Failed to fetch playlist's data",
"This playlist doesn't exist"
];
const [miscError] = expectedErrorMessages;
const errorMessage = (e as Error).message;
title = 'Error';
description = expectedErrorMessages.includes(errorMessage)
? errorMessage
: miscError;
this.response.status = description === miscError ? 500 : 404;
this.response.statusText = errorMessage;
}
return { playlist, title, description };
}