# Exception subtypes in Base

**URL:** <https://discourse.julialang.org/t/exception-subtypes-in-base/5875>\
**Category:** Internals & Design\
**Tags:** exception\
**Created:** [September 13, 2017, 8:31pm UTC](https://discourse.julialang.org/t/exception-subtypes-in-base/5875 "2017-09-13T20:31:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [September 13, 2017, 8:31pm UTC](https://discourse.julialang.org/t/exception-subtypes-in-base/5875/1 "2017-09-13T20:31:36Z")

</div>

As I was implementing an `Exception` subtype for the first time, I looked at some implementations in Base, for example [`ArgumentError`](https://github.com/JuliaLang/julia/blob/7e2e6c907d6c77fca02ef2657e870688daf64c35/base/boot.jl#L247). I was surprised by two things:

- a lot of the subtypes are `mutable`
- a lot of the subtypes don’t have concretely typed fields

On the other hand, the [documentation](https://docs.julialang.org/en/stable/manual/control-flow/#The-%5Bthrow()%5D(@ref)-function-1) refers to `UndefVarError` as an example of how to write a custom exception type, which is an immutable `struct` without abstract fields.

Just wondering: why is this? Also: does this have anything to do with the practice of throwing in a separate, `@noinline`’d function to achieve maximal performance? Ref e.g.: [https://github.com/JuliaLang/julia/pull/23088#issuecomment-320279238](https://github.com/JuliaLang/julia/pull/23088#issuecomment-320279238).

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 13, 2017, 8:58pm UTC](https://discourse.julialang.org/t/exception-subtypes-in-base/5875/2 "2017-09-13T20:58:25Z")

</div>

`mutable` is probably just there for historical reason. You don’t need to type the field though. It’s just and error and there’s almost no reason to type the field.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [September 13, 2017, 9:15pm UTC](https://discourse.julialang.org/t/exception-subtypes-in-base/5875/3 "2017-09-13T21:15:58Z")

</div>

I think the reason is that performance does not matter a lot since exceptions are only used in slow paths anyway, and as long as they are thrown from a separate `@noinline` function they does not slow the common path (as you noticed). But making them immutable would likely be a good idea. OTC, adding type parameters for fields is a bit more invasive and would slow down compilation by specializing on these types, so it might not be worth it.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [September 13, 2017, 9:29pm UTC](https://discourse.julialang.org/t/exception-subtypes-in-base/5875/4 "2017-09-13T21:29:36Z")

</div>

Thanks. I was just wondering if not concretely typing everything could make the non-throwing path slightly slower as well, but it seems that that is not the case. For:

```julia
struct ExceptionA <: Exception
    msg::String
end

mutable struct ExceptionB <: Exception
    msg::AbstractString
end

@noinline function a(x)
    x <= 0 || throw(ExceptionA("x > 0"))
end

@noinline function b(x)
    x <= 0 || throw(ExceptionB("x > 0"))
end

@noinline throw_a() = throw(ExceptionA("x > 0"))
@noinline function a2(x)
    x <= 0 || throw_a()
end

```

`a` and `b` have the same `code_llvm`, and `a2` is slightly faster than `a` and `b`, so the result from [https://github.com/JuliaLang/julia/pull/23088#issuecomment-320279238](https://github.com/JuliaLang/julia/pull/23088#issuecomment-320279238) holds.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [September 13, 2017, 9:41pm UTC](https://discourse.julialang.org/t/exception-subtypes-in-base/5875/5 "2017-09-13T21:41:27Z")

</div>

See also [https://github.com/JuliaLang/julia/pull/23469](https://github.com/JuliaLang/julia/pull/23469)
