refactor(http-recorder): use Schema.TaggedErrorClass for cassette errors (#26729)

This commit is contained in:
Kit Langton
2026-05-10 12:43:33 -04:00
committed by GitHub
parent b616543ac2
commit e45b6ef1de
3 changed files with 18 additions and 14 deletions
+5 -4
View File
@@ -1,4 +1,4 @@
import { Context, Data, Effect, FileSystem, Layer } from "effect" import { Context, Effect, FileSystem, Layer, Schema } from "effect"
import * as fs from "node:fs" import * as fs from "node:fs"
import * as path from "node:path" import * as path from "node:path"
import { secretFindings, type SecretFinding } from "./redaction" import { secretFindings, type SecretFinding } from "./redaction"
@@ -6,9 +6,10 @@ import { decodeCassette, encodeCassette, type Cassette, type CassetteMetadata, t
const DEFAULT_RECORDINGS_DIR = path.resolve(process.cwd(), "test", "fixtures", "recordings") const DEFAULT_RECORDINGS_DIR = path.resolve(process.cwd(), "test", "fixtures", "recordings")
export class CassetteNotFoundError extends Data.TaggedError("CassetteNotFoundError")<{ export class CassetteNotFoundError extends Schema.TaggedErrorClass<CassetteNotFoundError>()(
readonly cassetteName: string "CassetteNotFoundError",
}> { { cassetteName: Schema.String },
) {
override get message() { override get message() {
return `Cassette "${this.cassetteName}" not found` return `Cassette "${this.cassetteName}" not found`
} }
+6 -6
View File
@@ -1,13 +1,13 @@
import { Data, Effect, Ref, Scope } from "effect" import { Effect, Ref, Schema, Scope } from "effect"
import type * as CassetteService from "./cassette" import type * as CassetteService from "./cassette"
import type { CassetteNotFoundError } from "./cassette" import type { CassetteNotFoundError } from "./cassette"
import type { SecretFinding } from "./redaction" import { SecretFindingSchema } from "./redaction"
import type { CassetteMetadata, Interaction } from "./schema" import type { CassetteMetadata, Interaction } from "./schema"
export class UnsafeCassetteError extends Data.TaggedError("UnsafeCassetteError")<{ export class UnsafeCassetteError extends Schema.TaggedErrorClass<UnsafeCassetteError>()("UnsafeCassetteError", {
readonly cassetteName: string cassetteName: Schema.String,
readonly findings: ReadonlyArray<SecretFinding> findings: Schema.Array(SecretFindingSchema),
}> { }) {
override get message() { override get message() {
return `Refusing to write cassette "${this.cassetteName}" because it contains possible secrets: ${this.findings return `Refusing to write cassette "${this.cassetteName}" because it contains possible secrets: ${this.findings
.map((finding) => `${finding.path} (${finding.reason})`) .map((finding) => `${finding.path} (${finding.reason})`)
+7 -4
View File
@@ -95,10 +95,13 @@ export const redactHeaders = (
) )
} }
export type SecretFinding = { import { Schema } from "effect"
readonly path: string
readonly reason: string export const SecretFindingSchema = Schema.Struct({
} path: Schema.String,
reason: Schema.String,
})
export type SecretFinding = Schema.Schema.Type<typeof SecretFindingSchema>
export const secretFindings = (value: unknown): ReadonlyArray<SecretFinding> => export const secretFindings = (value: unknown): ReadonlyArray<SecretFinding> =>
stringEntries(value).flatMap((entry) => [ stringEntries(value).flatMap((entry) => [