Handling Custom Errors in Functional Programming vs Object-Oriented Programming

Hello everyone, I have a question regarding FP vs OOP practices and how to best define abstractions.

In typical OOP fashion I have an interface that describes common functionality and some classes that wish to implement it.
The issue here is that each implementation will raise different errors. Therefore, we are unable do know ahead on time the
Effect type-signature for each.

Is there a way to avoid the issue highlighted by the following example? What would be more idiomatic Effect solutions?
Ideally adding a new implementation would not imply modifying the interface.

import { Effect, Match, pipe} from 'effect';

// Base class
abstract class FooError {
  // As we are using 'string' type we will not 
  // have type information when catching errors
  // later! 
  constructor(readonly _tag: string){} 
}
interface Foo {
  bar: (value: string) => Effect.Effect<string, FooError>
}

// First implementation
class SomeError extends FooError {
  constructor(readonly message: string) {
    super("SomeError")
  }
}
class SomeImplementation implements Foo {
  bar = (v: string) => Effect.if( !!Math.round(Math.random()), {
    onTrue: () => Effect.succeed(v),
    onFalse: () => Effect.fail(new SomeError("SomeImplementation"))
  })
}

// Second implementation
class AnotherError extends FooError {
  constructor(readonly message: string) {
    super("AnotherError")
  }
}
class AnotherImplementation implements Foo {
  bar = (v: string) => Effect.if( !!Math.round(Math.random()), {
    onTrue: () => Effect.succeed(v),
    onFalse: () => Effect.fail(new AnotherError("AnotherImplementation"))
  })
}

// What would be best practices for a common interface but different errors?
function Question(foo: Foo) {
  return pipe(
    foo.bar("baz"),
    Effect.catchAll(e => pipe(
      Match.value(e),
      // How to have the type system guide in handling all possible errors here?
      Match.orElse(() => Effect.die("unhandled error"))
    ))
  )
}
Was this page helpful?