# A Julia equivalent to R's stop()?

**URL:** <https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [March 26, 2020, 9:40pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568 "2020-03-26T21:40:53Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![vlandau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlandau/32/8986_2.png) [@vlandau](https://discourse.julialang.org/u/vlandau)\
**Post date:** [March 26, 2020, 9:40pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/1 "2020-03-26T21:40:54Z")

</div>

Is there an equivalent in Julia to the `stop()` function in R? The nice thing about `stop()` is that it can be run from any scope (e.g. a function within a function) and it will throw an error and terminate the function that the user called.

I see that `throw()` in Julia does something similar, but I’d like to avoid printing a stack trace because it is not necessary for the info I’m trying to convey to users (e.g. two arrays provided as arguments are not the same size, but they need to be)

For now, I’m doing things like:

```julia
there_is_an_error = check_for_the_error(arg1, arg2) # returns a Bool
there_is_an_error && (@error "error message"; return)

```

I’d like to be able to have everything contained inside of `check_for_the_error()` to make the code more tidy.

Also open to suggestions for different approaches entirely.

Thanks!

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [March 26, 2020, 9:53pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/2 "2020-03-26T21:53:16Z")

</div>

`@assert` is generally what I would use for that, but it does print a stacktrace. It is a bit of a shorthand for what you are already doing.

```julia
julia> function gg(x,y)
       @assert x != y
       x+y
       end
gg (generic function with 1 method)

julia> gg(1,1)
ERROR: AssertionError: x != y
Stacktrace:
 [1] gg(::Int64, ::Int64) at ./REPL[49]:2
 [2] top-level scope at REPL[50]:1

```

---

<div class="post-metadata">

**Author:** ![vlandau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlandau/32/8986_2.png) [@vlandau](https://discourse.julialang.org/u/vlandau)\
**Post date:** [March 26, 2020, 10:01pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/3 "2020-03-26T22:01:23Z")

</div>

Thanks! Is there any way to suppress the stacktrace?

Ideally, the output would just look like this (no stacktrace, just a link to the line of code that causes it for developers’ reference):

```julia
┌ Error: A detailed error message
└ @ Main untitled-8dbe96a72552bcb86ffb481d3a092170:2

```

So that I can tell my users what is wrong (concisely) so they can fix it and try again. The user base I’m working with consists mostly of non-programmers, so I’m hoping to make things as straightforward and simple as possible.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [March 26, 2020, 10:06pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/4 "2020-03-26T22:06:29Z")

</div>

Not that I know of, but I’ve never looked into suppressing it.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [March 26, 2020, 10:53pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/5 "2020-03-26T22:53:02Z")

</div>

You could probably do something like:

```julia
struct Stop{T}
    answer::T
end

function stop(answer)
    throw(Stop(answer))
end

function start()
    stop(42)
end

try
    start()
    @info "No answer."
catch ex
    if isa(ex, Stop)
        @info "Exit with: $(ex.answer)"
    else
        rethrow(ex)
    end
end

```

This assumes that you are not already catching exceptions in the stack. If you are then you probably want to throw a “Stop” object that the other exception handlers can rethrow.

This is also not the approved way of unwinding the stack, throw is meant for errors not a normal exit.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 27, 2020, 6:40am UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/6 "2020-03-27T06:40:49Z")

</div>

> [@pixel27](#):
>
> This is also not the approved way of unwinding the stack, throw is meant for errors not a normal exit.

I think it may be the perfect solution for this use case.

Note also that R’s `stop()` is something like this, except that R, by default, does _not_ print a stacktrace — the user can request one with `traceback()`. I think that the idea is that error messages themselves convey enough information, which I do not think is true for any nontrivial computation.

---

<div class="post-metadata">

**Author:** ![vlandau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlandau/32/8986_2.png) [@vlandau](https://discourse.julialang.org/u/vlandau)\
**Post date:** [March 27, 2020, 4:55pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/7 "2020-03-27T16:55:44Z")

</div>

Agreed @Tamas_Papp – in my case, it’ll something like an input matrix having negative values when it shouldn’t, or matrix 1 not having the same dims as matrix 2, so really simple stuff.

Would I need to put that try/catch in the top-level function whenever I want to check for an error? I tried playing around with putting it inside a function within a function and wasn’t able to figure it out.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 27, 2020, 6:10pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/8 "2020-03-27T18:10:58Z")

</div>

I’m a little surprised this is so hard. I would have assumed that we’d have facilities for suppressing stacktraces.

One (non-ideal) approach to this would be to create a custom REPL mode where stack-traces may be suppressed. You can do this with my package [ReplMaker.jl](https://github.com/MasonProtter/ReplMaker.jl). Here’s what that might look like:

```julia
using ReplMaker
using REPL: LineEdit

struct QuietError{T}
    msg::T
end

globalize(ex) = ex
function globalize(ex::Expr)
    if ex.head == :block
        ex.args = globalize.(ex.args)
        ex
    elseif ex.head == :(=) || ex.head == :function
        :(global $ex)
    else
        ex
    end
end

function suppressable_stacktrace_parser(s)
    ex = globalize(Meta.parse(s))
    quote
        try
            $ex
        catch e
            if e isa QuietError
                @info "Exit with $e"
            else
                rethrow(e)
            end
        end
    end
end

iscomplete(x) = true
function iscomplete(ex::Expr)
    if ex.head == :incomplete
        false
    else
        true
    end
end

function valid_julia(s)
    input = String(take!(copy(LineEdit.buffer(s))))
    iscomplete(Meta.parse(input))
end

```

Now we can do

```julia
julia> initrepl(suppressable_stacktrace_parser,
                prompt_text="quiet-julia> ",
                prompt_color = :blue,
                start_key=')',
                mode_name="Suppressable-Error-Mode",
                valid_input_checker=valid_julia);
REPL mode Suppressable-Error-Mode initialized. Press ) to enter and backspace to exit.

julia> )

quiet-julia> f(x) = g(x + 1)
f (generic function with 1 method)

quiet-julia> g(x) = h(x/2)
g (generic function with 1 method)

quiet-julia> function h(x)
                 if x < 0
                     throw(QuietError("x must be positive, got $x"))
                 end
                 x
             end
h (generic function with 1 method)

quiet-julia> h(-5)
[ Info: Exit with QuietError{String}("x must be positive, got -5")

```

---

<div class="post-metadata">

**Author:** ![vlandau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlandau/32/8986_2.png) [@vlandau](https://discourse.julialang.org/u/vlandau)\
**Post date:** [March 27, 2020, 6:20pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/9 "2020-03-27T18:20:14Z")

</div>

Yeah, I found the potential workarounds to be too tricky to work with, so for now, I decided I would proceed with an approach similar to what I outlined in the origin post. I simplified it a bit so that `check_for_the_error(arg1, arg2)` will also throw the error message if needed and return a Bool specifying whether the error was triggered. So now I have this inside my top-level function:

```julia
check_for_the_error(arg1, arg2) && return

```

Not sure if this is the most ideal or elegant approach – but it was the cleanest I could get it, and works for my purposes.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 27, 2020, 6:40pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/10 "2020-03-27T18:40:42Z")

</div>

Maybe just make it a macro instead if you don’t like the `&& return`?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 28, 2020, 3:21pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/11 "2020-03-28T15:21:37Z")

</div>

> [@vlandau](#):
>
> Would I need to put that try/catch in the top-level function whenever I want to check for an error? I tried playing around with putting it inside a function within a function and wasn’t able to figure it out.

If you want to do something else than unwind and show the stack (eg provide an error message to the user), yes, you need a `try` / `catch`.

It can be in any caller, does not need to be top level.

That said, I don’t see why you are trying to avoid printing the stack trace. It is customary to do so in Julia (to the extent that you have to work hard to avoid it), and it aids debugging by providing some context for the error. This is important for generic code where methods can show up in a lot of different contexts.

---

<div class="post-metadata">

**Author:** ![vlandau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlandau/32/8986_2.png) [@vlandau](https://discourse.julialang.org/u/vlandau)\
**Post date:** [March 28, 2020, 5:51pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/12 "2020-03-28T17:51:56Z")

</div>

> [@Tamas\_Papp](#):
>
> I don’t see why you are trying to avoid printing the stack trace.

I hear you. My package is essentially one user-facing function. Users have to provide file paths to spatial data as arguments, and I want to throw an error for my users (who are not programmers) if the data layers do not align spatially, so they can go into a GIS program and fix them. I worry that anything else may just add to potential confusion.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 28, 2020, 6:05pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/13 "2020-03-28T18:05:45Z")

</div>

```julia
struct NoBackTraceException
    exc::Exception
end

function Base.showerror(io::IO, ex::NoBackTraceException, bt; backtrace=true)
    Base.with_output_color(get(io, :color, false) ? Base.error_color() : :nothing, io) do io
        showerror(io, ex.exc)
    end
    # look ma, no backtrace
end

f() = g()
g() = h()
h() = throw(NoBackTraceException(ErrorException("foo")))

```

```julia
julia> f()
ERROR: foo

julia>

```

Not really a good idea 🤷‍♂️

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 29, 2020, 7:52am UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/14 "2020-03-29T07:52:34Z")

</div>

> [@vlandau](#):
>
> Users have to provide file paths to spatial data as arguments, and I want to throw an error for my users (who are not programmers) if the data layers do not align spatially, so they can go into a GIS program and fix them.

It is hard to be specific without seeing some actual code, but something like

```julia
function do_everything(path)
    data = load_data(path)
    check_data_consistency(data) # errors can come from here
    ...
end

```

would provide a relatively flat stacktrace where you could include meaningful error messages about what went wrong. Incidentally, I find

> **[GitHub - jw3126/ArgCheck.jl: Package for checking function arguments](https://github.com/jw3126/ArgCheck.jl)**
>
> Package for checking function arguments. Contribute to jw3126/ArgCheck.jl development by creating an account on GitHub.

very useful for this purpose.

---

<div class="post-metadata">

**Author:** ![vlandau](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlandau/32/8986_2.png) [@vlandau](https://discourse.julialang.org/u/vlandau)\
**Post date:** [March 30, 2020, 4:13pm UTC](https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/15 "2020-03-30T16:13:34Z")

</div>

Thanks! I’ll check out that ArgCheck package.
