Question about macro and how to resolve/esc variables/expressions

Hi all :slight_smile:

Here is a little example code. I’m interested in the local var _error_msg :
local _error_msg = $(esc(sprint(showerror, error, catch_backtrace())))
So what I want is the error and catch_backtrace as string.

Using @macroexpand I see what I want as value. But just using it gives me an :e.

(with julia 1.8.3)

struct MissingDataException <: Exception 
    msg::String
end

Base.showerror(io::IO, ex::MissingDataException) =
    print(
        io, 
        """MissingDataException:
         $(ex.msg)
        """
    )


macro catch_missing_error(error, msg)
    quote
        local _error = $(esc(error))
        local _msg = $(esc(msg))
        local _error_msg = $(esc(sprint(showerror, error, catch_backtrace())))
        if _error isa MissingDataException
            @show _error
            @show _error_msg
        else
            @show _error
            @show _error_msg
        end

    end
end

try
    throw(MissingDataException("err"))
catch  e
    @catch_missing_error e "Hallo"
end

try
    throw(MissingDataException("err"))
catch  e
    @macroexpand @catch_missing_error e "Hallo"
end

Thanks

I think what you want is more along the lines of:

_error_msg = sprint(showerror, $(esc(error)), catch_backtrace())

In other words, you want catch_backtrace (and sprint) to be called at runtime, not at macro expansion time.

Full example:

julia> macro catch_missing_error(error, msg)
           quote
               local _error = $(esc(error))
               local _msg = $(esc(msg))
               local _error_msg = sprint(showerror, $(esc(error)), catch_backtrace())
               if _error isa MissingDataException
                   @show _error
                   @show _error_msg
               else
                   @show _error
                   @show _error_msg
               end
       
           end
       end
@catch_missing_error (macro with 1 method)

julia> @macroexpand @catch_missing_error e "Hallo"
quote
    #= REPL[1]:3 =#
    local var"#1#_error" = e
    #= REPL[1]:4 =#
    local var"#2#_msg" = "Hallo"
    #= REPL[1]:5 =#
    local var"#3#_error_msg" = Main.sprint(Main.showerror, e, Main.catch_backtrace())
    #= REPL[1]:6 =#
    if var"#1#_error" isa Main.MissingDataException
        #= REPL[1]:7 =#
        begin
            Base.println("_error = ", Base.repr(begin
                        #= show.jl:1047 =#
                        local var"#4#value" = var"#1#_error"
                    end))
            var"#4#value"
        end
        #= REPL[1]:8 =#
        begin
            Base.println("_error_msg = ", Base.repr(begin
                        #= show.jl:1047 =#
                        local var"#5#value" = var"#3#_error_msg"
                    end))
            var"#5#value"
        end
    else
        #= REPL[1]:10 =#
        begin
            Base.println("_error = ", Base.repr(begin
                        #= show.jl:1047 =#
                        local var"#6#value" = var"#1#_error"
                    end))
            var"#6#value"
        end
        #= REPL[1]:11 =#
        begin
            Base.println("_error_msg = ", Base.repr(begin
                        #= show.jl:1047 =#
                        local var"#7#value" = var"#3#_error_msg"
                    end))
            var"#7#value"
        end
    end
end