zio / zio-prelude

A lightweight, distinctly Scala take on functional abstractions, with tight ZIO integration
https://zio.dev/zio-prelude
Apache License 2.0
450 stars 115 forks source link

Custom error message for Assertion #1218

Open SvenW opened 11 months ago

SvenW commented 11 months ago

When adding a new type e.g:

  object Name extends Subtype[String] {
    override def assertion          = assert {
      hasLength(greaterThanOrEqualTo(1))
    }

It would be nice to be able to set a custom error message that's a bit more user friendly if the assertion fails. Right now this assertion would give us did not satisfy hasLength(greaterThanOrEqualTo(1)), which isn't that user friendly if returned to an actual user. It's possible to remap the error if we use make, e.g Name.make("my name") but that's a bit to easy to forget. Would it make sense to be able to set a custom error message on an Assertion?

guizmaii commented 11 months ago

Alternatively, you can use assertCustom

  object Name extends Subtype[String] {
    override def assertion = assertCustom { str =>
      if (str.trim.size >= 1) Right(()) else Left(AssertionError.Failure("This is an error"))
    }
  }

See https://github.com/zio/zio-prelude/blob/series/2.x/core-tests/shared/src/test/scala-2.12-2.13/zio/prelude/NewtypeSpecTypes212.scala#L7-L9

Note that this is in Scala2. In Scala3, the syntax is a bit different: https://github.com/zio/zio-prelude/blob/series/2.x/core-tests/shared/src/test/scala-3/zio/prelude/NewtypeSpecTypes.scala#L90-L96

SvenW commented 11 months ago

Alternatively, you can use assertCustom

  object Name extends Subtype[String] {
    override def assertion = assertCustom { str =>
      if (str.trim.size >= 1) Right(()) else Left(AssertionError.Failure("This is an error"))
    }
  }

See https://github.com/zio/zio-prelude/blob/series/2.x/core-tests/shared/src/test/scala-2.12-2.13/zio/prelude/NewtypeSpecTypes212.scala#L7-L9

Note that this is in Scala2. In Scala3, the syntax is a bit different: https://github.com/zio/zio-prelude/blob/series/2.x/core-tests/shared/src/test/scala-3/zio/prelude/NewtypeSpecTypes.scala#L90-L96

Thanks. I settled on this for now


  object Name extends Subtype[String] {
    override def assertion          = assertCustom { str =>
      hasLength(greaterThanOrEqualTo(1))(str).fold(_ => Left(AssertionError.Failure("can't be empty")), _ => Right(()))
    }
```. Would however still be nice to be able to just define an error message