Hyperlinkv0.8.0-beta.28

Channel

Channel.catchReasonsconsteffect/Channel.ts:5285
<
  K extends Types.Tags<OutErr>,
  OutErr,
  Cases extends {
    [RK in Types.ReasonTags<
      Types.ExtractTag<Types.NoInfer<OutErr>, K>
    >]+?: (
      reason: Types.ExtractReason<
        Types.ExtractTag<Types.NoInfer<OutErr>, K>,
        RK
      >,
      error: Types.NarrowReason<
        Types.ExtractTag<Types.NoInfer<OutErr>, K>,
        RK
      >
    ) => Channel<any, any, any, any, any, any, any>
  },
  OutElem2 = Types.unassigned,
  OutErr2 = never,
  OutDone2 = never,
  InElem2 = unknown,
  InErr2 = unknown,
  InDone2 = unknown,
  Env2 = never
>(
  errorTag: K,
  cases: Cases,
  orElse?:
    | ((
        reason: Types.ExcludeReason<
          Types.ExtractTag<Types.NoInfer<OutErr>, K>,
          Extract<keyof Cases, string>
        >,
        error: Types.OmitReason<
          Types.ExtractTag<Types.NoInfer<OutErr>, K>,
          Extract<keyof Cases, string>
        >
      ) => Channel<
        OutElem2,
        OutErr2,
        OutDone2,
        InElem2,
        InErr2,
        InDone2,
        Env2
      >)
    | undefined
): <OutElem, OutDone, InElem, InErr, InDone, Env>(
  self: Channel<OutElem, OutErr, OutDone, InElem, InErr, InDone, Env>
) => Channel<
  | OutElem
  | Exclude<OutElem2, Types.unassigned>
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<infer OutElem1, any, any, any, any, any, any>
        ? OutElem1
        : never
    }[keyof Cases],
  | Types.ExcludeTag<OutErr, K>
  | OutErr2
  | (OutElem2 extends Types.unassigned
      ? Types.ExtractTag<OutErr, K>
      : never)
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, infer OutErr1, any, any, any, any, any>
        ? OutErr1
        : never
    }[keyof Cases],
  | OutDone
  | OutDone2
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, infer OutDone1, any, any, any, any>
        ? OutDone1
        : never
    }[keyof Cases],
  InElem &
    InElem2 &
    {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, infer InElem1, any, any, any>
        ? InElem1
        : never
    }[keyof Cases],
  InErr &
    InErr2 &
    {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, any, infer InErr1, any, any>
        ? InErr1
        : never
    }[keyof Cases],
  InDone &
    InDone2 &
    {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, any, any, infer InDone1, any>
        ? InDone1
        : never
    }[keyof Cases],
  | Env
  | Env2
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, any, any, any, infer Env1>
        ? Env1
        : never
    }[keyof Cases]
>
<
  OutElem,
  OutErr,
  OutDone,
  InElem,
  InErr,
  InDone,
  Env,
  K extends Types.Tags<OutErr>,
  Cases extends {
    [RK in Types.ReasonTags<Types.ExtractTag<OutErr, K>>]+?: (
      reason: Types.ExtractReason<Types.ExtractTag<OutErr, K>, RK>,
      error: Types.NarrowReason<Types.ExtractTag<OutErr, K>, RK>
    ) => Channel<any, any, any, any, any, any, any>
  },
  OutElem2 = Types.unassigned,
  OutErr2 = never,
  OutDone2 = never,
  InElem2 = unknown,
  InErr2 = unknown,
  InDone2 = unknown,
  Env2 = never
>(
  self: Channel<OutElem, OutErr, OutDone, InElem, InErr, InDone, Env>,
  errorTag: K,
  cases: Cases,
  orElse?:
    | ((
        reason: Types.ExcludeReason<
          Types.ExtractTag<Types.NoInfer<OutErr>, K>,
          Extract<keyof Cases, string>
        >,
        error: Types.OmitReason<
          Types.ExtractTag<Types.NoInfer<OutErr>, K>,
          Extract<keyof Cases, string>
        >
      ) => Channel<
        OutElem2,
        OutErr2,
        OutDone2,
        InElem2,
        InErr2,
        InDone2,
        Env2
      >)
    | undefined
): Channel<
  | OutElem
  | Exclude<OutElem2, Types.unassigned>
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<infer OutElem1, any, any, any, any, any, any>
        ? OutElem1
        : never
    }[keyof Cases],
  | Types.ExcludeTag<OutErr, K>
  | OutErr2
  | (OutElem2 extends Types.unassigned
      ? Types.ExtractTag<OutErr, K>
      : never)
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, infer OutErr1, any, any, any, any, any>
        ? OutErr1
        : never
    }[keyof Cases],
  | OutDone
  | OutDone2
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, infer OutDone1, any, any, any, any>
        ? OutDone1
        : never
    }[keyof Cases],
  InElem &
    InElem2 &
    {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, infer InElem1, any, any, any>
        ? InElem1
        : never
    }[keyof Cases],
  InErr &
    InErr2 &
    {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, any, infer InErr1, any, any>
        ? InErr1
        : never
    }[keyof Cases],
  InDone &
    InDone2 &
    {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, any, any, infer InDone1, any>
        ? InDone1
        : never
    }[keyof Cases],
  | Env
  | Env2
  | {
      [RK in keyof Cases]: Cases[RK] extends (
        ...args: Array<any>
      ) => Channel<any, any, any, any, any, any, infer Env1>
        ? Env1
        : never
    }[keyof Cases]
>

Catches multiple reasons within a tagged error using an object of handlers.

error handling
Source effect/Channel.ts:5285169 lines
export const catchReasons: {
  <
    K extends Types.Tags<OutErr>,
    OutErr,
    Cases extends {
      [RK in Types.ReasonTags<Types.ExtractTag<Types.NoInfer<OutErr>, K>>]+?: (
        reason: Types.ExtractReason<Types.ExtractTag<Types.NoInfer<OutErr>, K>, RK>,
        error: Types.NarrowReason<Types.ExtractTag<Types.NoInfer<OutErr>, K>, RK>
      ) => Channel<any, any, any, any, any, any, any>
    },
    OutElem2 = Types.unassigned,
    OutErr2 = never,
    OutDone2 = never,
    InElem2 = unknown,
    InErr2 = unknown,
    InDone2 = unknown,
    Env2 = never
  >(
    errorTag: K,
    cases: Cases,
    orElse?:
      | ((
        reason: Types.ExcludeReason<Types.ExtractTag<Types.NoInfer<OutErr>, K>, Extract<keyof Cases, string>>,
        error: Types.OmitReason<Types.ExtractTag<Types.NoInfer<OutErr>, K>, Extract<keyof Cases, string>>
      ) => Channel<OutElem2, OutErr2, OutDone2, InElem2, InErr2, InDone2, Env2>)
      | undefined
  ): <OutElem, OutDone, InElem, InErr, InDone, Env>(
    self: Channel<OutElem, OutErr, OutDone, InElem, InErr, InDone, Env>
  ) => Channel<
    | OutElem
    | Exclude<OutElem2, Types.unassigned>
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<infer OutElem1, any, any, any, any, any, any> ? OutElem1 : never
    }[keyof Cases],
    | Types.ExcludeTag<OutErr, K>
    | OutErr2
    | (OutElem2 extends Types.unassigned ? Types.ExtractTag<OutErr, K> : never)
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, infer OutErr1, any, any, any, any, any> ? OutErr1 : never
    }[keyof Cases],
    | OutDone
    | OutDone2
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, infer OutDone1, any, any, any, any> ? OutDone1 : never
    }[keyof Cases],
    & InElem
    & InElem2
    & {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, infer InElem1, any, any, any> ? InElem1 : never
    }[keyof Cases],
    & InErr
    & InErr2
    & {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, any, infer InErr1, any, any> ? InErr1 : never
    }[keyof Cases],
    & InDone
    & InDone2
    & {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, any, any, infer InDone1, any> ? InDone1 : never
    }[keyof Cases],
    | Env
    | Env2
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, any, any, any, infer Env1> ? Env1 : never
    }[keyof Cases]
  >
  <
    OutElem,
    OutErr,
    OutDone,
    InElem,
    InErr,
    InDone,
    Env,
    K extends Types.Tags<OutErr>,
    Cases extends {
      [RK in Types.ReasonTags<Types.ExtractTag<OutErr, K>>]+?: (
        reason: Types.ExtractReason<Types.ExtractTag<OutErr, K>, RK>,
        error: Types.NarrowReason<Types.ExtractTag<OutErr, K>, RK>
      ) => Channel<any, any, any, any, any, any, any>
    },
    OutElem2 = Types.unassigned,
    OutErr2 = never,
    OutDone2 = never,
    InElem2 = unknown,
    InErr2 = unknown,
    InDone2 = unknown,
    Env2 = never
  >(
    self: Channel<OutElem, OutErr, OutDone, InElem, InErr, InDone, Env>,
    errorTag: K,
    cases: Cases,
    orElse?:
      | ((
        reason: Types.ExcludeReason<Types.ExtractTag<Types.NoInfer<OutErr>, K>, Extract<keyof Cases, string>>,
        error: Types.OmitReason<Types.ExtractTag<Types.NoInfer<OutErr>, K>, Extract<keyof Cases, string>>
      ) => Channel<OutElem2, OutErr2, OutDone2, InElem2, InErr2, InDone2, Env2>)
      | undefined
  ): Channel<
    | OutElem
    | Exclude<OutElem2, Types.unassigned>
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<infer OutElem1, any, any, any, any, any, any> ? OutElem1 : never
    }[keyof Cases],
    | Types.ExcludeTag<OutErr, K>
    | OutErr2
    | (OutElem2 extends Types.unassigned ? Types.ExtractTag<OutErr, K> : never)
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, infer OutErr1, any, any, any, any, any> ? OutErr1 : never
    }[keyof Cases],
    | OutDone
    | OutDone2
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, infer OutDone1, any, any, any, any> ? OutDone1 : never
    }[keyof Cases],
    & InElem
    & InElem2
    & {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, infer InElem1, any, any, any> ? InElem1 : never
    }[keyof Cases],
    & InErr
    & InErr2
    & {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, any, infer InErr1, any, any> ? InErr1 : never
    }[keyof Cases],
    & InDone
    & InDone2
    & {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, any, any, infer InDone1, any> ? InDone1 : never
    }[keyof Cases],
    | Env
    | Env2
    | {
      [RK in keyof Cases]: Cases[RK] extends
        (...args: Array<any>) => Channel<any, any, any, any, any, any, infer Env1> ? Env1 : never
    }[keyof Cases]
  >
} = dual((args) => isChannel(args[0]), (self, errorTag, cases, orElse) => {
  let keys: Set<string>
  return catch_(self, (error) => {
    if (
      isTagged(error, errorTag) &&
      hasProperty(error, "reason") &&
      hasProperty(error.reason, "_tag") &&
      String.isString(error.reason._tag)
    ) {
      const reason = error.reason as { readonly _tag: string }
      keys ??= new Set(Object.keys(cases))
      if (keys.has(reason._tag)) {
        return (cases as any)[reason._tag](reason as any, error)
      }
      return orElse ? orElse(reason, error) as any : fail(error) as any
    }
    return fail(error) as any
  })
})
Referenced by 1 symbols