Use tagged errors in tests

This commit is contained in:
elpresidank 2026-06-04 08:10:09 -05:00
parent c4500f216e
commit c48927b7c5
8 changed files with 104 additions and 23 deletions

View file

@ -1,5 +1,6 @@
import { describe, expect, it } from "@effect/vitest";
import { ConfigProvider, Effect, Fiber } from "effect";
import * as S from "effect/Schema";
import {
Embeddings,
EmbeddingsService,
@ -18,6 +19,18 @@ import {
type PubSubBackend,
} from "../index.js";
class WaitForTimeout extends S.TaggedErrorClass<WaitForTimeout>()(
"WaitForTimeout",
{ label: S.String },
) {}
class TestProviderUnavailable extends S.TaggedErrorClass<TestProviderUnavailable>()(
"TestProviderUnavailable",
{ message: S.String },
) {}
const isWaitForTimeout = S.is(WaitForTimeout);
function createMessage<T>(value: T, properties: Record<string, string> = {}): Message<T> {
return {
value: () => value,
@ -36,14 +49,14 @@ const waitFor = (condition: () => boolean, label: string) =>
return;
}
if (Date.now() > deadline) {
reject(new Error(`Timed out waiting for ${label}`));
reject(WaitForTimeout.make({ label }));
return;
}
setTimeout(check, 5);
};
check();
}),
catch: (error) => error,
catch: (error) => isWaitForTimeout(error) ? error : WaitForTimeout.make({ label }),
});
class RecordingProducer<T> implements BackendProducer<T> {
@ -206,7 +219,13 @@ describe("EmbeddingsService", () => {
const backend = new EmbeddingsBackend();
const embeddings = Embeddings.of({
embed: Effect.fn("FailingEmbeddings.embed")(() =>
Effect.fail(embeddingsError("test.embed", new Error("provider unavailable"), "test")),
Effect.fail(
embeddingsError(
"test.embed",
TestProviderUnavailable.make({ message: "provider unavailable" }),
"test",
),
),
),
});

View file

@ -1,5 +1,6 @@
import { describe, expect, it } from "@effect/vitest";
import { ConfigProvider, Effect, Fiber } from "effect";
import * as S from "effect/Schema";
import {
FlowProcessor,
MessagingRuntimeLive,
@ -17,6 +18,13 @@ import {
type PubSubBackend,
} from "../index.js";
class WaitForTimeout extends S.TaggedErrorClass<WaitForTimeout>()(
"WaitForTimeout",
{ label: S.String },
) {}
const isWaitForTimeout = S.is(WaitForTimeout);
function createMessage<T>(value: T, properties: Record<string, string> = {}): Message<T> {
return {
value: () => value,
@ -35,14 +43,14 @@ const waitFor = (condition: () => boolean, label: string) =>
return;
}
if (Date.now() > deadline) {
reject(new Error(`Timed out waiting for ${label}`));
reject(WaitForTimeout.make({ label }));
return;
}
setTimeout(check, 5);
};
check();
}),
catch: (error) => error,
catch: (error) => isWaitForTimeout(error) ? error : WaitForTimeout.make({ label }),
});
class RecordingProducer<T> implements BackendProducer<T> {

View file

@ -2,18 +2,24 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import { makeNatsBackend } from "../backend/nats.js";
const natsMock = vi.hoisted(() => {
const S = require("effect/Schema");
const encoder = new TextEncoder();
const decoder = new TextDecoder();
class MockNatsError extends Error {
readonly code: string;
private readonly apiCode: number | undefined;
class MockNatsError extends S.TaggedErrorClass()(
"MockNatsError",
{
apiCode: S.optional(S.Number),
code: S.String,
message: S.String,
},
) {
constructor(code: string, apiCode?: number) {
super(code);
this.name = "NatsError";
this.code = code;
this.apiCode = apiCode;
super({
apiCode,
code,
message: code,
});
}
jsError() {

View file

@ -1,5 +1,6 @@
import { describe, expect, it } from "@effect/vitest";
import { Effect } from "effect";
import * as S from "effect/Schema";
import {
PubSub,
makeAsyncProcessor,
@ -13,6 +14,11 @@ import {
type PubSubBackend,
} from "../index.js";
class RuntimeServicesTestError extends S.TaggedErrorClass<RuntimeServicesTestError>()(
"RuntimeServicesTestError",
{ message: S.String },
) {}
class FakeProducer<T> implements BackendProducer<T> {
readonly sent: Array<{ readonly message: T; readonly properties?: Record<string, string> }> = [];
closeCount = 0;
@ -75,7 +81,7 @@ class FakePubSubBackend implements PubSubBackend {
class FailingProducerBackend extends FakePubSubBackend {
override async createProducer<T>(): Promise<BackendProducer<T>> {
throw new Error("producer unavailable");
throw RuntimeServicesTestError.make({ message: "producer unavailable" });
}
}
@ -99,7 +105,7 @@ const makeRecordingProcessor = (
const makeFailingProcessor = (config: ProcessorConfig) =>
makeAsyncProcessor(config, {
run: async () => {
throw new Error("processor failed");
throw RuntimeServicesTestError.make({ message: "processor failed" });
},
});