A nodeless Hyperlink.client(tag) was built with no ambient RpcClient.Protocol.
Replaces Effect's opaque "Service not found: …/Protocol" die with a remediation message naming
the three ways to connect. The Layer still requires RpcClient.Protocol in R (compile-time)
and keeps E = never (this replaces a defect, not a typed channel callers already matched);
catch via Exit / _tag when probing an unsatisfied build.
export class class MissingClientProtocolclass MissingClientProtocol {
message: string;
name: string;
stack: string;
cause: unknown;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
_tag: Tag;
resource: string;
}
A nodeless
Hyperlink.client
(tag) was built with no ambient
RpcClient.Protocol
.
Replaces Effect's opaque "Service not found: …/Protocol" die with a remediation message naming
the three ways to connect. The Layer still requires RpcClient.Protocol in R (compile-time)
and keeps E = never (this replaces a defect, not a typed channel callers already matched);
catch via Exit / _tag when probing an unsatisfied build.
MissingClientProtocol extends import DataData.const TaggedError: <"MissingClientProtocol">(tag: "MissingClientProtocol") => new <A>(args: VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & {
readonly _tag: "MissingClientProtocol";
} & Readonly<A>
Creates a tagged error class with a _tag discriminator.
When to use
Use when you need domain errors with discriminated-union handling.
Details
Like
Error
, but instances also carry a readonly _tag property,
enabling Effect.catchTag and Effect.catchTags for tag-based recovery.
The _tag is excluded from the constructor argument. Yielding an instance
inside Effect.gen fails the effect with this error.
Example (Recovering by tag)
import { Data, Effect } from "effect"
class NotFound extends Data.TaggedError("NotFound")<{
readonly resource: string
}> {}
class Forbidden extends Data.TaggedError("Forbidden")<{
readonly reason: string
}> {}
const program = Effect.gen(function*() {
return yield* new NotFound({ resource: "/users/42" })
})
const recovered = program.pipe(
Effect.catchTag("NotFound", (e) =>
Effect.succeed(`missing: ${e.resource}`))
)
TaggedError("MissingClientProtocol")<{
readonly resource: stringresource: string;
}> {
override get MissingClientProtocol.message: stringmessage() {
return (
`Hyperlink.client("${this.resource: stringresource}") has no ambient RpcClient.Protocol. ` +
`Connect it with Node.connect(node) / Hyperlink.client(tag, node), ` +
`Hyperlink.clientHttp(tag, target), or Hyperlink.socketClient(node) ` +
`(or Layer.provide a protocolHttp / protocolWebsocket / protocolIpc layer).`
);
}
}