Astro — error handling
The loader throws exactly one error type, GhostwritrError, and it fails closed: a broken config or an unreachable feed stops the build rather than shipping an empty or partial collection. There are two distinct moments where it can throw.
Two failure points
Section titled “Two failure points”Config errors throw synchronously, the moment ghostwritr() is called in src/content.config.ts. A missing or blank siteId, or an invalid staticBaseUrl, throws right there with code CONFIG and status 0 — the build never starts.
Feed errors throw during the build, when the loader’s load runs. A missing feed, a network failure, or a malformed payload throws while astro build is syncing the collection. The build fails.
import { defineCollection } from "astro:content";import { ghostwritr } from "@ghostwritr/astro";
// Throws synchronously if GHOSTWRITR_SITE_ID is unset → build never starts.export const collections = { articles: defineCollection({ loader: ghostwritr({ siteId: import.meta.env.GHOSTWRITR_SITE_ID }), }),};Inspecting the error
Section titled “Inspecting the error”GhostwritrError carries a status (the HTTP status, or 0 for config/network errors) and a code:
import { GhostwritrError } from "@ghostwritr/astro";
try { // ...whatever wrapped the loader/feed call} catch (err) { if (err instanceof GhostwritrError) { err.code; // see the table below err.status; // HTTP status, or 0 for config/network err.details; // extra context (e.g. the duplicate slug, the malformed body) }}instanceof GhostwritrError works identically across @ghostwritr/astro, @ghostwritr/next, and @ghostwritr/feed — they all re-export the same class.
code | status | meaning |
|---|---|---|
CONFIG | 0 | bad options — missing siteId, invalid staticBaseUrl |
NETWORK_ERROR | 0 | the request never completed (DNS, offline, fetch threw) |
NOT_FOUND | 404 | no feed for this siteId — fails closed |
RATE_LIMITED | 429 | feed origin rate-limited the build |
SERVER_ERROR | 5xx | feed origin error |
INVALID_RESPONSE | 0 | malformed feed, a non-JSON body, or a duplicate slug |
The exported GhostwritrErrorCode type is open (a union plus string), so handle unknown codes gracefully.
Practical handling
Section titled “Practical handling”You usually want the build to fail loudly — that’s the safe default and it needs no code. Catch GhostwritrError only when you have a deliberate fallback, for example a CI step that distinguishes a transient NETWORK_ERROR (retry the build) from a CONFIG error (fix the env and never retry). Don’t swallow NOT_FOUND into an empty collection; an empty blog deployed silently is worse than a failed build.
See Error handling for the cross-SDK error model.