Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.15 KB | None | 0 0
  1. /*
  2. * My application is splitted in several modules, possibly independently built and
  3. * distributed.
  4. * I have a Base error trait for the whole application.
  5. *
  6. * Each module has its own business error defined by a module base error trait which
  7. * extends BaseError.
  8. *
  9. * I want to have a common framework to manage bridging errors between modules so
  10. * that a module can use the other ones and subsume error type to its own, especially
  11. * in the canonical exemple:
  12. *
  13. * ```
  14. * for {
  15. * a <- module1
  16. * b <- module2
  17. * } yield {
  18. * ...
  19. * } : error of kind module 3
  20. * ```
  21. *
  22. * The bridging could be done with a "chain" error kind that encapsulated one error module
  23. * in an other: `ErrorModule2.Chain("some explanation", errorModule1)`
  24. *
  25. * Finally, I want minimum boilerplate for that. How is it usually done?
  26. */
  27. object errors {
  28. trait BaseError {
  29. def msg: String
  30.  
  31. }
  32.  
  33. trait BaseChainError[E <: BaseError] extends BaseError {
  34. def cause: E
  35. def hint: String
  36. def msg = s"${hint}; cause was: ${cause.getClass.getSimpleName}: ${cause.msg}"
  37. }
  38. }
  39.  
  40. object TestImplicits {
  41. import scalaz.zio._
  42. import scalaz.zio.syntax._
  43.  
  44. object module1 {
  45. import com.normation.errors._
  46. sealed trait M_1_Error extends BaseError
  47. object M_1_Error {
  48. final case class BusinessError1(msg: String) extends M_1_Error
  49. final case class Chained[E <: BaseError](hint: String, cause: E) extends M_1_Error with BaseChainError[E]
  50. }
  51.  
  52. object M_1_Result {
  53. // implicits ?
  54. }
  55.  
  56. object service1 {
  57. def doStuff(param: String): IO[M_1_Error, String] = param.succeed
  58. }
  59. }
  60.  
  61. object module2 {
  62. import com.normation.errors._
  63. sealed trait M_2_Error extends BaseError
  64. object M_2_Error {
  65. final case class MissingImportantStuff(msg: String) extends M_2_Error
  66. final case class Chained[E <: BaseError](hint: String, cause: E) extends M_2_Error with BaseChainError[E]
  67. }
  68. object M_2_Result {
  69. // implicits
  70. }
  71. object service2 {
  72. def doStuff(param: Int): IO[M_2_Error, Int] = param.succeed
  73. }
  74. }
  75.  
  76. object testModule {
  77. import module1._
  78. import module2._
  79.  
  80. import com.normation.errors._
  81. sealed trait M_3_Error extends BaseError
  82. object M_3_Error {
  83. final case class Oups(msg: String) extends M_3_Error
  84. final case class Chained[E <: BaseError](hint: String, cause: E) extends M_3_Error with BaseChainError[E]
  85. }
  86. object M_3_Result {
  87. // implicits ?
  88. }
  89.  
  90. import module1.M_1_Result._
  91. import module2.M_2_Result._
  92. import M_3_Result._
  93.  
  94. /*
  95. * I would like all of that to be possible, with the minimum boilerplate,
  96. * and the maximum homogeneity between modules
  97. */
  98. object service {
  99.  
  100. // need error adpatation 1 toward 2
  101. def test0(a: String): IO[M_2_Error, Int] = service1.doStuff(a)
  102.  
  103. // need error adpatation 1 toward 3
  104. def test1(a: String): IO[M_3_Error, Int] = service1.doStuff(a)
  105.  
  106. // need error adpatation 1 and 2 toward 3
  107. def test2(a: String, b: Int): IO[M_3_Error, (String, Int)] = {
  108. for {
  109. x <- service1.doStuff(a)
  110. y <- service2.doStuff(b)
  111. } yield {
  112. (x, y)
  113. }
  114. }
  115. }
  116. }
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement