Errors

How problems in content and config are reported.

View as Markdown

tomekit reports every broken file in one pass, pointing at where to fix it.

Content errors

A problem in a document is printed as file:line:column: message, with the file relative to the project root.

Terminal
content/posts/hello.md:2:1: title: Invalid input: expected string, received undefined
content/posts/typo.md:2:1: author: no document in collection "authors" has the slug "adaa". Fix the slug, or add a document with it to "authors"

An entry from a loader without a file is named by its collection and slug instead: pages.get("about"): message.

  • vite build fails, listing every broken file.
  • The dev server logs the errors, shows them in the error overlay at the first one's location, and keeps serving everything else. Broken documents are left out until you fix them.

Warnings

Warnings don't stop anything. Each one says what happens because of it:

Terminal
posts: directory "content/posts" has no files, so the collection is empty
posts: no files in "content/posts" match "**/*.md", but it has 12 other files, so the collection is empty

Config errors

A config that can't be used fails vite build. The dev server logs it and keeps running, but tomekit/content fails to load until you fix the config:

  • ConfigLoadError: importing tomekit.config.ts threw, eg on a syntax error
  • MissingDefaultExportError: the file doesn't export default defineConfig(...)
  • InvalidConfigError: the config breaks a rule, eg a collection name that isn't a valid identifier, or a collection without a loader

Without the tomekit() plugin, importing collections throws MissingPluginError, while importing a collection by name fails first, with the module "does not provide an export named" it. Add the plugin to vite.config.ts in both cases, or outside Vite run Node with --import tomekit/register (see Register).

Catching errors

Every error is a class exported from tomekit, so check it with instanceof:

ClassExtendsThrown when
TomekitErrorErrorThe base of every error
BrokenContentErrorTomekitErrorA build has content errors. errors holds each ContentError
ContentErrorTomekitErrorOne problem in a document. It has file, line, column, collection and slug
ConfigErrorTomekitErrorThe base of config errors
TransformErrorTomekitErrorThe base of errors from transform, set as a ContentError's cause
PluginErrorTomekitErrorThe base of errors from the Vite plugin
MissingPluginErrorPluginErrortomekit/content is imported without the tomekit() plugin or tomekit/register
UncacheablePluginErrorPluginErrorcached() gets something other than one plugin with a transform hook
DuplicateCachedPluginErrorPluginErrorTwo plugins wrapped in cached() have the same name (see MDX)

Vite wraps errors thrown by plugins and keeps the originals under errors:

import { BrokenContentError } from "tomekit";
import { build } from "vite";

const failure = await build().catch((cause: unknown) => cause);
const errors =
  failure instanceof Error && "errors" in failure ? failure.errors : [];

const broken = Array.isArray(errors)
  ? errors.find((error) => error instanceof BrokenContentError)
  : undefined;

broken?.errors[0]?.file; // "content/posts/hello.md"