Solid · guide

Handle a wrong value

A value of the wrong kind is left out, the rest of the reply is read, and you are told where it was.

Install it
pnpm add @niscorp/solid zod
Step 1 of 4

The shape

The schema is the shape you asked the model for. Solid needs it before any text arrives.

The shape
import { z } from 'zod';
import { createStream } from '@niscorp/solid';

const Suggestion = z.object({
  show: z.string(),
  seats: z.array(z.string()),
  price_cents: z.number(),
  why: z.string(),
});
Step 2 of 4

A reply with two things wrong

The seats are a sentence where a list was asked for, and there is a discount nobody asked for.

A reply with two things wrong
const reply = '{"show":"The Tempest","seats":"C4 and C5","discount":10,"price_cents":7600,"why":"Row C."}';
Step 3 of 4

Read it

Solid knows what kind a value is from its first character. One of another kind than the schema has there is skipped whole, and so is a key the schema does not have. What the stream held before stays.

onError is called for each, with the path. Solid throws nothing for a wrong value, and reading goes on.

Read it
const stream = createStream({ schema: Suggestion });
stream.onError((error) => console.log(error.path, '·', error.message));
stream.write(reply);
console.log(JSON.stringify(stream.current()));
Step 4 of 4

The same reply, strictly

With mode: 'strict' the first wrong value or unknown key ends it: the piece that carried it is dropped whole, the stream takes no more text, and final() rejects. The default is recover, the one above.

The same reply, strictly
const strict = createStream({ schema: Suggestion, mode: 'strict' });
strict.onError((error) => console.log('strict ·', error.message));
strict.write(reply);
await strict.final().catch((error: Error) => console.log(error.message));
Then

Run it.

Two errors, each with its path, and then the object: the show, the price and the reason are there, and the seats are still the empty list. Strictly, one error and a rejected final().

Run it
npx tsx wrong.mts
It prints
seats · [solid] seats: expected array, got string
discount · [solid] discount: expected <unknown path>, got number
{"show":"The Tempest","seats":[],"price_cents":7600,"why":"Row C."}
strict · [solid] seats: expected array, got string
[solid] stream failed validation