Skip to content

Commit

Permalink
Show top level location for any exc in eval(Expr(:error, exc))
Browse files Browse the repository at this point in the history
Previously this only worked when `exc` was a `String`.
  • Loading branch information
c42f committed Jun 17, 2023
1 parent 1a6cd97 commit 8caba95
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
21 changes: 15 additions & 6 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,19 +656,28 @@ static void check_macro_rename(jl_sym_t *from, jl_sym_t *to, const char *keyword
jl_errorf("cannot rename non-macro \"%s\" to macro \"%s\" in \"%s\"", n1, n2, keyword);
}

// Format msg and eval `throw(ErrorException(msg)))` in module `m`.
// Used in `jl_toplevel_eval_flex` instead of `jl_errorf` so that the error
// Eval `throw(ErrorException(msg)))` in module `m`.
// Used in `jl_toplevel_eval_flex` instead of `jl_throw` so that the error
// location in julia code gets into the backtrace.
static void jl_eval_errorf(jl_module_t *m, const char* fmt, ...)
static void jl_eval_throw(jl_module_t *m, jl_value_t *exc)
{
jl_value_t *throw_ex = (jl_value_t*)jl_exprn(jl_call_sym, 2);
JL_GC_PUSH1(&throw_ex);
jl_exprargset(throw_ex, 0, jl_builtin_throw);
jl_exprargset(throw_ex, 1, exc);
jl_toplevel_eval_flex(m, throw_ex, 0, 0);
JL_GC_POP();
}

// Format error message and call jl_eval
static void jl_eval_errorf(jl_module_t *m, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
jl_exprargset(throw_ex, 1, jl_vexceptionf(jl_errorexception_type, fmt, args));
jl_value_t *exc = jl_vexceptionf(jl_errorexception_type, fmt, args);
va_end(args);
jl_toplevel_eval_flex(m, throw_ex, 0, 0);
JL_GC_PUSH1(&exc);
jl_eval_throw(m, exc);
JL_GC_POP();
}

Expand Down Expand Up @@ -875,7 +884,7 @@ jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int
jl_eval_errorf(m, "malformed \"%s\" expression", jl_symbol_name(head));
if (jl_is_string(jl_exprarg(ex, 0)))
jl_eval_errorf(m, "syntax: %s", jl_string_data(jl_exprarg(ex, 0)));
jl_throw(jl_exprarg(ex, 0));
jl_eval_throw(m, jl_exprarg(ex, 0));
}
else if (jl_is_symbol(ex)) {
JL_GC_POP();
Expand Down
9 changes: 8 additions & 1 deletion test/backtrace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ let bt, found = false
end

# Syntax error locations appear in backtraces
let trace = try
eval(Expr(:error, 1))
catch
stacktrace(catch_backtrace())
end
@test trace[1].func === Symbol("top-level scope")
end
let trace = try
include_string(@__MODULE__,
"""
Expand All @@ -221,7 +228,7 @@ let trace = try
end
@test trace[1].func === Symbol("top-level scope")
@test trace[1].file === :a_filename
@test trace[1].line == 2
@test trace[1].line == 3
end

# issue #45171
Expand Down

0 comments on commit 8caba95

Please sign in to comment.