Louis F. Louis F. - 2 months ago 17
Scala Question

Scala error modeling

I am having my mind stuck on how to model error handling in the following case:

I have

CommonErrors
which are errors that can occur for all my methods

I also have specific errors such as:
Error1
,
Error2
,
Error3


So we have in the end

DoAErrors
=
CommonErrors
+
Error1
+
Error2


DoBErrors
=
CommonErrors
+
Error2
+
Error3


and the method signatures :

doA() Either[DoAErrors, DoAResult]
doB() Either[DoBErrors, DoBResult]


To be nice I would like to use sealed traits so the clients of my library can safely pattern match on
DoAErrors
and
DoBErrors
and catch the common + specifics errors. So far what I tried :

sealed trait CommonErrors
… extends CommonErrors
… extends CommonErrors

sealed trait DoAErrors extends CommonErrors
Error1 extends DoAErrors

sealed trait DoBErrors extends CommonErrors

Error2 extends DoAErrors with DoBErrors
Error3 extends DoBErrors


The problem comes from the fact that
doA()
and
doB()
internally call a method that returns a
CommonError
and it is not possible to retrofit
CommonErrors
in
DoA
nor
DoB
errors. How would one model this case?

Thanks for the help !

Answer

From your description, it sounds like CommonErrors is actually one possible type of both DoAErrors and DoBErrors. In other words - the following statements are true:

CommonErrors IS A DoAErrors

CommonErrors IS A DoBErrors

This usually means that CommonErrors should extend the other types and not vice versa.

And indeed - the following code compiles and allows easy pattern-matching for call sites of doA and doB:

sealed trait DoAErrors
sealed trait DoBErrors
sealed trait CommonErrors extends DoAErrors with DoBErrors

class CommonE1 extends CommonErrors
class CommonE2 extends CommonErrors
class Error1 extends DoAErrors
class Error2 extends DoAErrors with DoBErrors
class Error3 extends DoBErrors

object Test {

  private def common(): Either[CommonErrors, String] = Left(new CommonE1())
  def doA(): Either[DoAErrors, String] = common()
  def doB(): Either[DoBErrors, String] = common()
}