mirror of
https://github.com/walkxcode/dashboard-icons.git
synced 2025-11-18 09:37:30 +01:00
refactor(api): improve API error handling and revalidation
- Update API utilities to use new ApiError class - Improve error handling and status code management - Enhance revalidation logic for better cache management
This commit is contained in:
@@ -1,25 +1,17 @@
|
||||
import { unstable_cache } from "next/cache"
|
||||
import { METADATA_URL } from "@/constants"
|
||||
import type { IconFile, IconWithName } from "@/types/icons"
|
||||
|
||||
/**
|
||||
* Custom error class for API errors
|
||||
*/
|
||||
export class ApiError extends Error {
|
||||
status: number
|
||||
|
||||
constructor(message: string, status = 500) {
|
||||
super(message)
|
||||
this.name = "ApiError"
|
||||
this.status = status
|
||||
}
|
||||
}
|
||||
import { ApiError } from "@/lib/errors"
|
||||
import type { AuthorData, IconFile, IconWithName } from "@/types/icons"
|
||||
|
||||
/**
|
||||
* Fetches all icon data from the metadata.json file
|
||||
* Uses fetch with revalidate for caching
|
||||
*/
|
||||
export async function getAllIcons(): Promise<IconFile> {
|
||||
try {
|
||||
const response = await fetch(METADATA_URL)
|
||||
const response = await fetch(METADATA_URL, {
|
||||
next: { revalidate: 3600 },
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new ApiError(`Failed to fetch icons: ${response.statusText}`, response.status)
|
||||
@@ -93,16 +85,14 @@ export async function getIconData(iconName: string): Promise<IconWithName | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches author data from GitHub API
|
||||
* Fetch author data from GitHub API (raw function without caching)
|
||||
*/
|
||||
export async function getAuthorData(authorId: number) {
|
||||
async function fetchAuthorData(authorId: number) {
|
||||
try {
|
||||
const response = await fetch(`https://api.github.com/user/${authorId}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
|
||||
"Cache-Control": "public, max-age=86400",
|
||||
},
|
||||
next: { revalidate: 86400 }, // Revalidate cache once a day
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -134,6 +124,26 @@ export async function getAuthorData(authorId: number) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached version of fetchAuthorData
|
||||
* Uses unstable_cache with tags for on-demand revalidation
|
||||
* Revalidates every 86400 seconds (24 hours)
|
||||
* Cache key: author-{authorId}
|
||||
*
|
||||
* This prevents hitting GitHub API rate limits by caching author data
|
||||
* across multiple page builds and requests.
|
||||
*/
|
||||
export async function getAuthorData(authorId: number): Promise<AuthorData> {
|
||||
return unstable_cache(
|
||||
async () => await fetchAuthorData(authorId),
|
||||
[`author-${authorId}`],
|
||||
{
|
||||
revalidate: 86400,
|
||||
tags: ["authors", `author-${authorId}`],
|
||||
}
|
||||
)()
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches total icon count
|
||||
*/
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
"use server"
|
||||
|
||||
import { revalidatePath, revalidateTag } from "next/cache"
|
||||
import { revalidatePath, updateTag } from "next/cache"
|
||||
|
||||
/**
|
||||
* Revalidate the community page cache
|
||||
* Can be called from server actions after submission approval/rejection
|
||||
* Uses updateTag for immediate updates (read-your-writes semantics)
|
||||
*/
|
||||
export async function revalidateCommunityPage() {
|
||||
revalidatePath("/community")
|
||||
revalidateTag("community-gallery")
|
||||
updateTag("community-gallery")
|
||||
}
|
||||
|
||||
/**
|
||||
* Revalidate a specific community icon page
|
||||
* Use this when a specific submission's status changes
|
||||
* Uses updateTag for immediate updates (read-your-writes semantics)
|
||||
*/
|
||||
export async function revalidateCommunityIcon(iconName: string) {
|
||||
revalidatePath(`/community/${iconName}`)
|
||||
updateTag("community-gallery")
|
||||
updateTag("community-submission")
|
||||
updateTag("community-gallery-record")
|
||||
}
|
||||
|
||||
/**
|
||||
* Revalidate all submission-related caches
|
||||
* Uses updateTag for immediate updates (read-your-writes semantics)
|
||||
*/
|
||||
export async function revalidateSubmissions() {
|
||||
revalidateTag("community-gallery")
|
||||
updateTag("community-gallery")
|
||||
updateTag("community-submission")
|
||||
updateTag("community-gallery-record")
|
||||
revalidatePath("/community")
|
||||
revalidatePath("/dashboard")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user