Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
b637aa7
remove handle error page.
khajavi Mar 7, 2022
f1d9519
expected errors vs. unexpected errors.
khajavi Feb 1, 2022
a2a6f88
don't type unexpected errors.
khajavi Feb 2, 2022
3beec64
add a general note for when importing effects.
khajavi Feb 2, 2022
498c387
modeling domain errors using algebraic data types.
khajavi Feb 3, 2022
2ba1680
typed errors using union types.
khajavi Feb 3, 2022
244d7f6
using union type to be more specific about error types.
khajavi Feb 4, 2022
432829d
don't reflexively log errors.
khajavi Feb 6, 2022
a3e1f60
exceptional and unexceptional effects.
khajavi Feb 6, 2022
9b20bb5
imperative vs. functional error handling.
khajavi Feb 7, 2022
db7c4d6
lossless error model.
khajavi Feb 8, 2022
4eeb7dc
either and absolve.
khajavi Feb 8, 2022
abe6ff8
some note about orDie.
khajavi Feb 8, 2022
d6ca41f
sandbox and unsandbox.
khajavi Feb 10, 2022
d54ec33
zio defects and fatal errors.
khajavi Feb 17, 2022
e020a12
default
khajavi Feb 18, 2022
29a8466
converting defects to failures and vice versa.
khajavi Feb 18, 2022
8bfa3f3
refining and unrefining the type of the error channel.
khajavi Feb 19, 2022
25b5b65
absorbing or resurrecting vs. dying.
khajavi Feb 19, 2022
32a3abb
converting defects to failures.
khajavi Feb 19, 2022
ba2214f
write an introduction to sandboxing errors.
khajavi Feb 19, 2022
92fb9d4
a better title for sandbox section.
khajavi Feb 19, 2022
8297779
three type of errors in zio.
khajavi Feb 20, 2022
9125e57
add examples.
khajavi Feb 20, 2022
1d091e8
add tslib.
khajavi Feb 21, 2022
71e561d
create a new page for error management.
khajavi Apr 1, 2022
d3d16eb
some and unsome zio values.
khajavi Feb 21, 2022
4499cc6
use compile-only modifier for mdoc blocks.
khajavi Mar 24, 2022
09eeaa1
creating a ZIO of optional values.
khajavi Feb 22, 2022
58c6cd8
ZIO.getOrFail constructor.
khajavi Feb 22, 2022
da2551e
explain more on getOrFail constructors.
khajavi Feb 22, 2022
b4df371
flattening optional error types.
khajavi Feb 22, 2022
216f528
ZIO#getOrElse
khajavi Feb 22, 2022
75f616c
document the ZIO#someOrElseZIO operator.
khajavi Feb 22, 2022
5516c58
someOrFail operation.
khajavi Feb 22, 2022
bb01297
add a note on some or fail exception.
khajavi Feb 22, 2022
6e58d1f
fix the example of ZIO#sandboxWith.
khajavi Feb 22, 2022
ba5940f
introduction for error management.
khajavi Feb 23, 2022
5280144
add example for sandboxWith operator.
khajavi Feb 23, 2022
cbcb735
fallback on optional error types.
khajavi Feb 23, 2022
2a879cd
ZIO#orElseFail.
khajavi Feb 23, 2022
312c5d1
more note on ZIO#orElseFail and also add documentation for ZIO#orElse…
khajavi Feb 23, 2022
b7c0400
document ZIO#orElse operator.
khajavi Feb 23, 2022
e4328e0
clean up code blocks and their imports.
khajavi Feb 23, 2022
fe9485a
document ZIO#orElseEither.
khajavi Feb 23, 2022
1062747
document fold operators.
khajavi Feb 24, 2022
04c14b3
document ZIO#foldTraceZIO
khajavi Feb 24, 2022
360528c
remove extra table.
khajavi Feb 24, 2022
17fc2b8
write a note on fiber interruption and the fold operator.
khajavi Feb 24, 2022
7cfea23
retry and retryOrElse operators.
khajavi Feb 27, 2022
388075b
retryOrElseEither.
khajavi Feb 27, 2022
55afac1
ZIO#retryN
khajavi Feb 27, 2022
63cc3eb
retryUntil and retryUntilZIO
khajavi Feb 27, 2022
097b617
retryUntilEqual
khajavi Feb 27, 2022
e0b62fd
retryWhile, retryWhileZIO and retryWhileEquals
khajavi Feb 27, 2022
9d9dd53
timeout operator
khajavi Feb 28, 2022
937abc0
cleanup
khajavi Feb 28, 2022
fe3d323
using ZIO#disconnect with ZIO#timeout.
khajavi Feb 28, 2022
37932c4
ZIO#timeoutTo
khajavi Feb 28, 2022
740646e
producing error message in case of timeout.
khajavi Feb 28, 2022
8d8cc38
cleanup absolve and either section.
khajavi Feb 28, 2022
850174f
cleanup sandbox examples.
khajavi Feb 28, 2022
866c7b3
catchAll convert exceptional effects to unexceptional effects.
khajavi Mar 1, 2022
a0d5ae8
catchSome section
khajavi Mar 1, 2022
5efe3f8
note on catching defects and fiber interruptions.
khajavi Mar 3, 2022
fd6a6e9
catching defects.
khajavi Mar 3, 2022
f1bc91b
catching all errors.
khajavi Mar 3, 2022
95e2331
catching traces.
khajavi Mar 4, 2022
483cd5f
typed errors don't guarantee the absence of defects and interruptions.
khajavi Mar 4, 2022
d5ec5c2
fix mdoc's error.
khajavi Mar 4, 2022
bf99f07
cause is a semiring and show how the cause designed.
khajavi Mar 4, 2022
924e88e
cause internals.
khajavi Mar 24, 2022
3f7824a
failure cause.
khajavi Mar 4, 2022
16ed24e
wip on cause page.
khajavi Mar 24, 2022
aa079e9
wip on cause.
khajavi Mar 24, 2022
c3fa63c
then cause for sequential errors.
khajavi Mar 24, 2022
84b3558
cleanup the cause page.
khajavi Mar 5, 2022
aef9b59
clean-up.
khajavi Mar 5, 2022
598bdaf
definition of the exit data type.
khajavi Mar 6, 2022
8f28177
cause internals.
khajavi Mar 6, 2022
93ff3de
add result type.
khajavi Mar 7, 2022
c271b47
fix mdoc failure.
khajavi Mar 7, 2022
a2e27ea
fix `mdoc -watch` breakage.
khajavi Mar 8, 2022
31b9605
update mdoc version.
khajavi Mar 8, 2022
f405d86
complete failure section.
khajavi Mar 8, 2022
37718f0
clean up fatal errors section.
khajavi Mar 8, 2022
a231000
reorder topics.
khajavi Mar 8, 2022
7b2273d
fix title.
khajavi Mar 9, 2022
01118ed
sequential and parallel errors.
khajavi Mar 9, 2022
170e59f
change header levels.
khajavi Mar 9, 2022
8c5cfd2
exposing parallel failure errors.
khajavi Mar 9, 2022
4137d6e
error accumulation.
khajavi Mar 12, 2022
60c5cb9
introduce ZIO#validate and ZIO#validatePar operators.
khajavi Mar 14, 2022
0478d21
cleanup.
khajavi Mar 14, 2022
370e645
add function definitions.
khajavi Mar 14, 2022
72930ea
write a note about ZIO#validateWith.
khajavi Mar 14, 2022
f622c3a
merging the error channel into success channel.
khajavi Mar 14, 2022
66a7bb6
flipping the error and success channels.
khajavi Mar 15, 2022
cdd08c3
firstSuccessOf
khajavi Mar 15, 2022
0a71c3b
add more explanation.
khajavi Mar 15, 2022
c50f551
nonOrFail
khajavi Mar 16, 2022
b2d9a7d
getOrFail and nonOrFail.
khajavi Mar 16, 2022
1afb60e
rejecting some values.
khajavi Mar 16, 2022
30e969a
fix method name.
khajavi Mar 16, 2022
6ed6c87
map and flatMap on error channels.
khajavi Mar 17, 2022
4e6c014
introduce all error refinement methods.
khajavi Mar 19, 2022
3bd42fd
introduce left/unleft, right/unright operations.
khajavi Mar 19, 2022
a14ee4e
cleanup.
khajavi Mar 19, 2022
42d38fc
converting optional values to optional errors and vice versa.
khajavi Mar 20, 2022
09ea377
rename left and right section.
khajavi Mar 20, 2022
f6bcb5f
uncovering the underlying cause of an effect.
khajavi Mar 21, 2022
72f0a6b
cleanup
khajavi Mar 21, 2022
489c87a
catching non-fatal.
khajavi Mar 21, 2022
60195f6
filtering the success channel values.
khajavi Mar 21, 2022
fd48646
complete ZIO#someOrElse section.
khajavi Mar 22, 2022
2f895c6
tapping.
khajavi Mar 22, 2022
cb98df6
tapping errors.
khajavi Mar 22, 2022
9dcb01d
add definition of ZIO#resurrect and ZIO#absorb.
khajavi Mar 22, 2022
772dd75
add definition of ZIO#either and ZIO#absolve.
khajavi Mar 22, 2022
9b2cbec
add tapSome.
khajavi Mar 23, 2022
505fde2
write a note about why we need to catch defects.
khajavi Mar 23, 2022
2a557b0
remove extra note.
khajavi Mar 23, 2022
48ff4bf
add definition of all catch methods.
khajavi Mar 23, 2022
ead8039
cleanup.
khajavi Mar 23, 2022
4b53db3
proofreading.
khajavi Mar 24, 2022
77df888
cleanup zio.md page.
khajavi Mar 24, 2022
519e350
fix mdoc errors.
khajavi Mar 24, 2022
dea7072
fix validate output.
khajavi Mar 24, 2022
979ac5c
examples
khajavi Mar 25, 2022
96b87a6
cleanup.
khajavi Mar 25, 2022
8a7bdbd
remove default services from the zio environment.
khajavi Apr 1, 2022
513ad21
Merge branch 'series/2.x' into error-handling-documentation
khajavi Apr 14, 2022
08245de
fix imports.
khajavi Apr 15, 2022
88e272e
fix typo.
khajavi May 5, 2022
2aee9ea
Merge branch 'series/2.x' into error-handling-documentation
khajavi May 5, 2022
6d6b56c
use ZIO instead of IO.
khajavi May 5, 2022
c0f1440
fix mdoc errors.
khajavi May 5, 2022
7e1fc83
Merge branch 'series/2.x' into error-handling-documentation
khajavi May 9, 2022
3f40ebc
regarding removal of RuntimeConfig.
khajavi May 9, 2022
b6edcae
Merge branch 'series/2.x' into error-handling-documentation
khajavi May 12, 2022
408d8ee
fix warning.
khajavi May 12, 2022
ab70df2
Switch ZIO version for 1.0 docs to 1.0.14
atooni May 23, 2022
a247740
Upgrade to docusaurus beta-20
atooni May 23, 2022
976fea7
Add appId to docusaurus config
atooni May 23, 2022
353c52b
Make Overview link version aware
atooni May 23, 2022
7f36fab
testing versioned links
atooni May 23, 2022
3352cf9
another try on versioned links
atooni May 23, 2022
15e9287
Trying a version relative link
atooni May 23, 2022
cedfeb9
yet another relative link try
atooni May 23, 2022
d19c3e8
Playing with config vars
atooni May 23, 2022
64e0682
trying docsVersion without statis override
atooni May 23, 2022
df2fd73
Try version specific navbar
atooni May 23, 2022
6230151
Swizzling Navbar component for version resolution
atooni May 24, 2022
e10e933
Switch navbar links to doc links
atooni May 24, 2022
fd439ef
Correct docid in sidebar
atooni May 24, 2022
a2b4ee1
Break site build on broken links
atooni May 24, 2022
a033bd0
Add Prezi to adopters list (#6864)
bmateusz May 27, 2022
9eaa6bb
Fix ZIO 1.x sidebars (#6863)
khajavi May 27, 2022
22921ee
issue #5878 - Backport ThreadLocalBridge (#5980)
dkarlinsky May 30, 2022
4541a37
chore(deps): update zio.version to v1.0.15 (#6899)
renovate[bot] Jun 8, 2022
8e479eb
workaround.
khajavi Jun 12, 2022
7236493
remove empty article.
khajavi Jun 12, 2022
e7ed1eb
prepare for publish.
khajavi Jun 15, 2022
025ace7
fix mdoc errors.
khajavi Jun 15, 2022
e2c4ed9
minor change.
khajavi Jun 15, 2022
2280450
update zio-kafka ecosystem page.
khajavi Jun 15, 2022
8889ef7
add 7 and 8 arg for check, checkM, checkAll and checkAllM (#6916)
strokyl Jun 16, 2022
a7b9233
initial work.
khajavi Jun 20, 2022
cc83f54
conclusion section.
khajavi Jun 21, 2022
cfd03ea
fix sidebar.
khajavi Jun 21, 2022
ccce90c
fix site build problem.
khajavi Jun 21, 2022
70f4523
initial work.
khajavi Jun 22, 2022
dae3104
Fix frontmatters (#6949)
vigoo Jun 24, 2022
877af03
Merge branch 'master' into merge-master-to-series-2.x
khajavi Jun 24, 2022
3372a5a
Merge remote-tracking branch 'origin/series/2.x' into zio2/consolidat…
atooni Jun 24, 2022
dea23e3
Use master for version 1 build for now
atooni Jun 24, 2022
8fdd553
remove extra usecases sidebar.
khajavi Jun 24, 2022
0b170a1
Merge remote-tracking branch 'milad/error-handling-documentation' int…
atooni Jun 24, 2022
d8d065c
Merge remote-tracking branch 'milad/merge-master-to-series-2.x' into …
atooni Jun 24, 2022
e6f5fa9
Merge remote-tracking branch 'milad/docker-deployment' into series2.x…
atooni Jun 24, 2022
3628bc3
orrect navbar
atooni Jun 24, 2022
eb46f5e
Switch back version 1 docs ref
atooni Jun 24, 2022
ce9e725
Remove docusaurus site build from sbt message
atooni Jun 24, 2022
a15f53d
Fix some broken links
atooni Jun 24, 2022
95aaf2d
Merge remote-tracking branch 'milad/kafka-tutorial' into series2.x/co…
atooni Jun 24, 2022
3077a28
Merge remote-tracking branch 'milad/monitor-zio-application' into ser…
atooni Jun 24, 2022
dfbf57b
Fix checkSite build step
atooni Jun 24, 2022
abb97e5
Remove obsolete link
atooni Jun 24, 2022
7d863e6
Replace occurrences of ZTrace with Trace
atooni Jun 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ lazy val docs = project.module
unusedCompileDependenciesFilter -= moduleFilter("org.scalameta", "mdoc"),
scalacOptions -= "-Yno-imports",
scalacOptions -= "-Xfatal-warnings",
Compile / fork := false,
scalacOptions ~= { _ filterNot (_ startsWith "-Ywarn") },
scalacOptions ~= { _ filterNot (_ startsWith "-Xlint") },
crossScalaVersions --= List(Scala211, Scala3),
Expand Down
4 changes: 2 additions & 2 deletions core/shared/src/main/scala/zio/ZIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1858,8 +1858,8 @@ sealed trait ZIO[-R, +E, +A]
* ZIO.succeed(5 / 0) *> ZIO.fail(DomainError())
*
* val caught: IO[DomainError, Unit] =
* veryBadIO.sandboxWith(_.catchSome {
* case Cause.Die(_: ArithmeticException)=>
* veryBadIO.sandboxWith[Any, DomainError, Unit](_.catchSome {
* case Cause.Die(_: ArithmeticException, _)=>
* // Caught defect: divided by zero!
* ZIO.succeed(0)
* })
Expand Down
2 changes: 1 addition & 1 deletion docs/about/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
id: index
id: about_index
title: "About ZIO"
---

Expand Down
51 changes: 26 additions & 25 deletions docs/datatypes/contextual/zlayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,40 +227,41 @@ Below is a complete working example:
```scala mdoc:compile-only
import zio._

object MainApp extends ZIOAppDefault {
final case class DatabaseConfig()
case class DatabaseConfig()

object DatabaseConfig {
val live = ZLayer.succeed(DatabaseConfig())
}
object DatabaseConfig {
val live = ZLayer.succeed(DatabaseConfig())
}

final case class Database(databaseConfig: DatabaseConfig)
case class Database(databaseConfig: DatabaseConfig)

object Database {
val live: ZLayer[DatabaseConfig, Nothing, Database] =
ZLayer.fromFunction(Database.apply _)
}
object Database {
val live: ZLayer[DatabaseConfig, Nothing, Database] =
ZLayer.fromFunction(Database.apply _)
}

final case class Analytics()
case class Analytics()

object Analytics {
val live: ULayer[Analytics] = ZLayer.succeed(Analytics())
}
object Analytics {
val live: ULayer[Analytics] = ZLayer.succeed(Analytics())
}

final case class Users(database: Database, analytics: Analytics)
case class Users(database: Database, analytics: Analytics)

object Users {
val live = ZLayer.fromFunction(Users.apply _)
}
object Users {
val live = ZLayer.fromFunction(Users.apply _)
}

final case class App(users: Users, analytics: Analytics) {
def execute: UIO[Unit] =
ZIO.debug(s"This app is made from ${users} and ${analytics}")
}
case class App(users: Users, analytics: Analytics) {
def execute: UIO[Unit] =
ZIO.debug(s"This app is made from ${users} and ${analytics}")
}

object App {
val live = ZLayer.fromFunction(App.apply _)
}
object App {
val live = ZLayer.fromFunction(App.apply _)
}

object MainApp extends ZIOAppDefault {

def run =
ZIO
Expand Down
249 changes: 225 additions & 24 deletions docs/datatypes/core/cause.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,243 @@ id: cause
title: "Cause"
---

`Cause[E]` is a description of a full story of failure, which is included in an [Exit.Failure](exit.md). Many times in ZIO something can fail for a value of type `E`, but there are other ways things can fail too.
The `ZIO[R, E, A]` effect is polymorphic in values of type `E` and we can work with any error type that we want, but there is a lot of information that is not inside an arbitrary `E` value. So as a result ZIO needs somewhere to store things like **unexpected error or defects**, **stack and execution traces**, **cause of fiber interruptions**, and so forth.

`IO[E, A]` is polymorphic in values of type `E` and we can work with any error type that we want, but there is a lot of information that is not inside an arbitrary `E` value. So as a result ZIO needs somewhere to store things like **unexpected exceptions or defects**, **stack and execution traces**, **cause of fiber interruptions**, and so forth.
ZIO is very strict about preserving the full information related to a failure. It captures all type of errors into the `Cause` data type. ZIO uses the `Cause[E]` data type to store the full story of failure. So its error model is **lossless**. It doesn't throw information related to the failure result. So we can figure out exactly what happened during the operation of our effects.

It is important to note that `Cause` is the underlying data type for the ZIO data type, and we don't usually deal with it directly. Even though it is not a data type that we deal with very often, anytime we want, we can access the `Cause` data structure, which gives us total access to all parallel and sequential errors in our codebase.

## Cause Internals

ZIO uses a data structure from functional programming called a _semiring_ for the `Cause` data type. **It allows us to take a base type `E` that represents the error type and then capture the sequential and parallel composition of errors in a fully lossless fashion**.

The following snippet shows how the `Cause` is designed as a semiring data structure:

```scala
sealed abstract class Cause[+E] extends Product with Serializable { self =>
import Cause._
def trace: Trace = ???

final def ++[E1 >: E](that: Cause[E1]): Cause[E1] = Then(self, that)
final def &&[E1 >: E](that: Cause[E1]): Cause[E1] = Both(self, that)
}

object Cause extends Serializable {
case object Empty extends Cause[Nothing]
final case class Fail[+E](value: E, override val trace: Trace) extends Cause[E]
final case class Die(value: Throwable, override val trace: Trace) extends Cause[Nothing]
final case class Interrupt(fiberId: FiberId, override val trace: Trace) extends Cause[Nothing]
final case class Stackless[+E](cause: Cause[E], stackless: Boolean) extends Cause[E]
final case class Then[+E](left: Cause[E], right: Cause[E]) extends Cause[E]
final case class Both[+E](left: Cause[E], right: Cause[E]) extends Cause[E]
}
```

Using the `Cause` data structure described above, ZIO can capture all errors inside the application.

## Cause Variations
`Cause` has several variations which encode all the cases:

1. `Fail[+E](value: E)` contains the cause of expected failure of type `E`.
There are several causes for various errors. In this section, we will describe each of these causes. We will see how they can be created manually or how they will be automatically generated as the underlying error management data type of a ZIO application.

### Empty

The `Empty` cause indicates the lack of errors. We use `Cause.empty` constructor to create an `Empty` cause. Using `ZIO.failCause` we can create a ZIO effect that has an empty cause:

```scala mdoc:compile-only
import zio._

ZIO.failCause(Cause.empty).cause.debug
// Empty
```

Also, we can use the `ZIO#cause` to uncover the underlying cause of an effect. For example, we know that the `ZIO.succeed(5)` has no errors. So, let's check that:

```
ZIO.succeed(5).cause.debug
// Empty

ZIO.attempt(5).cause.debug
// Empty
```

### Fail

2. `Die(value: Throwable)` contains the cause of a defect or in other words, an unexpected failure of type `Throwable`. If we have a bug in our code and something throws an unexpected exception, that information would be described inside a `Die`.
The `Fail` cause indicates the cause of an expected error of type `E`. We can create one using the `Cause.fail` constructor:

3. `Interrupt(fiberId)` contains information of the fiber id that causes fiber interruption.
```scala mdoc:compile-only
import zio._

ZIO.failCause(Cause.fail("Oh uh!")).cause.debug
// Fail(Oh uh!,Trace(Runtime(2,1646395282),Chunk(<empty>.MainApp.run(MainApp.scala:4))))
```

4. `Traced(cause, trace)` stores stack traces and execution traces.
Let's uncover the cause of some ZIO effects especially when we combine them:

5. `Meta(cause, data)`
```scala mdoc:compile-only
import zio._

ZIO.fail("Oh uh!").cause.debug
// Fail(Oh uh!,Trace(Runtime(2,1646395627),Chunk(<empty>.MainApp.run(MainApp.scala:3))))

6. `Both(left, right)` & `Then(left, right)` store a composition of two parallel and sequential causes, respectively. Sometimes fibers can fail for more than one reason. If we are doing two things at once and both of them fail then we actually have two errors. Examples:
+ If we perform ZIO's analog of try-finally (e.g. ZIO#ensuring), and both of `try` and `finally` blocks fail, then their causes are encoded with `Then`.
+ If we run two parallel fibers with `zipPar` and both of them fail, then their causes are encoded with `Both`.
(ZIO.fail("Oh uh!") *> ZIO.dieMessage("Boom!") *> ZIO.interrupt).cause.debug
// Fail(Oh uh!,Trace(Runtime(2,1646396370),Chunk(<empty>.MainApp.run(MainApp.scala:6))))

Let's try to create some of these causes:
(ZIO.fail("Oh uh!") <*> ZIO.fail("Oh Error!")).cause.debug
// Fail(Oh uh!,Trace(Runtime(2,1646396419),Chunk(<empty>.MainApp.run(MainApp.scala:9))))

```scala mdoc:silent
val myApp: ZIO[Any, String, Int] =
for {
i <- ZIO.succeed(5)
_ <- ZIO.fail("Oh uh!")
_ <- ZIO.dieMessage("Boom!")
_ <- ZIO.interrupt
} yield i
myApp.cause.debug
// Fail(Oh uh!,Trace(Runtime(2,1646397126),Chunk(<empty>.MainApp.myApp(MainApp.scala:13),<empty>.MainApp.run(MainApp.scala:17))))
```

### Die

The `Die` cause indicates a defect or in other words, an unexpected failure of type `Throwable`. Additionally, it contains the stack traces of the occurred defect. We can use the `Cause.die` to create one:

```scala mdoc:compile-only
import zio._
for {
failExit <- ZIO.fail("Oh! Error!").exit
dieExit <- ZIO.succeed(5 / 0).exit
thenExit <- ZIO.fail("first").ensuring(ZIO.die(throw new Exception("second"))).exit
bothExit <- ZIO.fail("first").zipPar(ZIO.die(throw new Exception("second"))).exit
fiber <- ZIO.sleep(1.second).fork
_ <- fiber.interrupt
interruptionExit <- fiber.join.exit
} yield ()

ZIO.failCause(Cause.die(new Throwable("Boom!"))).cause.debug
// Die(java.lang.Throwable: Boom!,Trace(Runtime(2,1646479908),Chunk(<empty>.MainApp.run(MainApp.scala:3))))
```

## Lossless Error Model
ZIO is very strict about preserving the full information related to a failure. ZIO captures all types of errors into the `Cause` data type. So its error model is lossless. It doesn't throw away any information related to the failure result. So we can figure out exactly what happened during the operation of our effects.
If we have a bug in our code and something throws an unexpected exception, that information would be described inside a `Die`. Let try to investigate some ZIO codes that will die:

```scala mdoc:compile-only
import zio._

ZIO.succeed(5 / 0).cause.debug
// Die(java.lang.ArithmeticException: / by zero,Trace(Runtime(2,1646480112),Chunk(zio.internal.FiberContext.runUntil(FiberContext.scala:538),<empty>.MainApp.run(MainApp.scala:3))))

ZIO.dieMessage("Boom!").cause.debug
// Stackless(Die(java.lang.RuntimeException: Boom!,Trace(Runtime(2,1646398246),Chunk(<empty>.MainApp.run(MainApp.scala:7)))),true)
```

It is worth noting that the latest example is wrapped by the `Stackless` cause in the previous example. We will discuss the `Stackeless` further, but for now, it is enough to know that the `Stackeless` include fewer stack traces for the `Die` cause.

### Interrupt

The `Interrupt` cause indicates a fiber interruption which contains information of the _fiber id_ of the interrupted fiber and also the corresponding stack strace. Let's try an example of:

```scala mdoc:compile-only
import zio._

ZIO.interrupt.cause.debug
// Interrupt(Runtime(2,1646471715),Trace(Runtime(2,1646471715),Chunk(<empty>.MainApp.run(MainApp.scala:3))))

ZIO.never.fork
.flatMap(f => f.interrupt *> f.join)
.cause
.debug
// Interrupt(Runtime(2,1646472025),Trace(Runtime(13,1646472025),Chunk(<empty>.MainApp.run(MainApp.scala:7))))
```

### Stackless

The `Stackless` cause is to store stack traces and execution traces. It has a boolean stackless flag which denotes that the ZIO runtime should print the full stack trace of the inner cause or just print the few lines of it.

For example, the `ZIO.dieMessage` uses the `Stackless`:

```scala mdoc:compile-only
import zio._

ZIO.dieMessage("Boom!").cause.debug
// Stackless(Die(java.lang.RuntimeException: Boom!,Trace(Runtime(2,1646477970),Chunk(<empty>.MainApp.run(MainApp.scala:3)))),true)
```

So when we run it the following stack traces will be printed:

```scala
timestamp=2022-03-05T11:08:19.530710679Z level=ERROR thread=#zio-fiber-0 message="Exception in thread "zio-fiber-2" java.lang.RuntimeException: Boom!
at <empty>.MainApp.run(MainApp.scala:3)"
```

While the `ZIO.die` doesn't use `Stackless` cause:

```scala mdoc:compile-only
import zio._

ZIO.die(new Throwable("Boom!")).cause.debug
// Die(java.lang.Exception: Boom!,Trace(Runtime(2,1646479093),Chunk(<empty>.MainApp.run(MainApp.scala:3))))
```

So it prints the full stack trace:

```scala
timestamp=2022-03-05T11:19:12.666418357Z level=ERROR thread=#zio-fiber-0 message="Exception in thread "zio-fiber-2" java.lang.Exception: Boom!
at MainApp$.$anonfun$run$1(MainApp.scala:4)
at zio.ZIO$.$anonfun$die$1(ZIO.scala:3384)
at zio.internal.FiberContext.runUntil(FiberContext.scala:255)
at zio.internal.FiberContext.run(FiberContext.scala:115)
at zio.internal.ZScheduler$$anon$1.run(ZScheduler.scala:151)
at <empty>.MainApp.run(MainApp.scala:4)"
```

### Both

When we are doing parallel computation, the effect can fail for more than one reason. If we are doing two things at once and both of them fail then we actually have two errors. So, the `Both` cause stores the composition of two parallel causes.

For example, if we run two parallel fibers with `zipPar` and all of them fail, so their causes will be encoded with `Both`:

```scala mdoc:compile-only
import zio._

val myApp: ZIO[Any, String, Unit] =
for {
f1 <- ZIO.fail("Oh uh!").fork
f2 <- ZIO.dieMessage("Boom!").fork
_ <- (f1 <*> f2).join
} yield ()
myApp.cause.debug
// Both(Fail(Oh uh!,Trace(Runtime(13,1646481219),Chunk(<empty>.MainApp.myApp(MainApp.scala:5)))),Stackless(Die(java.lang.RuntimeException: Boom!,Trace(Runtime(14,1646481219),Chunk(<empty>.MainApp.myApp(MainApp.scala:6)))),true))
```

Ir we run the `myApp` in the stack trace we can see two exception traces occurred on two separate fibers:

```scala
timestamp=2022-03-05T12:37:46.831096692Z level=ERROR thread=#zio-fiber-0 message="Exception in thread "zio-fiber-13" java.lang.String: Oh uh!
at <empty>.MainApp.myApp(MainApp.scala:5)
Exception in thread "zio-fiber-14" java.lang.RuntimeException: Boom!
at <empty>.MainApp.myApp(MainApp.scala:6)"
```

Other parallel operators are also the same, for example, ZIO encode the underlying cause of the `(ZIO.fail("Oh uh!") <&> ZIO.dieMessage("Boom!"))` with `Both` cause.

### Then

ZIO uses `Then` cause to encode sequential errors. For example, if we perform ZIO's analog of `try-finally` (e.g. `ZIO#ensuring`), and both of `try` and `finally` blocks fail, so their causes are encoded with `Then`:

```scala mdoc:compile-only
import zio._

val myApp =
ZIO.fail("first")
.ensuring(ZIO.die(throw new Exception("second")))

myApp.cause.debug
// Then(Fail(first,Trace(Runtime(2,1646486975),Chunk(<empty>.MainApp.myApp(MainApp.scala:4),<empty>.MainApp.myApp(MainApp.scala:5),<empty>.MainApp.run(MainApp.scala:7)))),Die(java.lang.Exception: second,Trace(Runtime(2,1646486975),Chunk(zio.internal.FiberContext.runUntil(FiberContext.scala:538),<empty>.MainApp.myApp(MainApp.scala:5),<empty>.MainApp.run(MainApp.scala:7)))))
```

If we run the `myApp` effect, we can see the following stack trace:

```scala
timestamp=2022-03-05T13:30:17.335173071Z level=ERROR thread=#zio-fiber-0 message="Exception in thread "zio-fiber-2" java.lang.String: first
at <empty>.MainApp.myApp(MainApp.scala:4)
at <empty>.MainApp.myApp(MainApp.scala:5)
Suppressed: java.lang.Exception: second
at MainApp$.$anonfun$myApp$3(MainApp.scala:5)
at zio.ZIO$.$anonfun$die$1(ZIO.scala:3384)
at zio.internal.FiberContext.runUntil(FiberContext.scala:255)
at zio.internal.FiberContext.run(FiberContext.scala:115)
at zio.internal.ZScheduler$$anon$1.run(ZScheduler.scala:151)
at zio.internal.FiberContext.runUntil(FiberContext.scala:538)
at <empty>.MainApp.myApp(MainApp.scala:5)"
```

As we can see in the above stack trace, the _first_ failure was suppressed by the _second_ defect.
Loading