Try catch question

I use

    try
          JSON.parsefile(fname) do stuff
             content = "Nothing ..."          
          end
     catch
         content = "File "*fname*" not found! ";
     end

But it always returns that file was not found despite that JSON.parsefile(fname) works …

It should be now…

You seem to be confused about what the do syntax does. Manual entry for do. This

JSON.parsefile(fname) do stuff
    content = "Nothing ..."          
end

is equivalent to

JSON.parsefile(stuff -> content = "Nothing ...", fname)

i.e. the do syntax invokes the function (JSON.parsefile) with an anonymous function as the first argument. Since there is no method of JSON.parsefile that accepts a function as first argument this will always be a MethodError and you will always end up in the catch block. Indeed, if you had tried just the code in your try block you would have seen this.

5 Likes

To elaborate a bit more on @fredrikekre’s comment:

JSON.parsefile(fname) do stuff
    content = "Nothing ..."          
end

This statement would need to call a version of JSON.parsefile() that defines:

parsefile(function_to_do::Function, filename::AbstractString, [other optional arguments here])

And that version of parsefile() would need to correctly call (expect) the anonymous function you defined. In other words, it would have to call:

function_to_do(stuff)

somewhere in its code. This does not happen by magic. Someone has to implement this version of the function. But if you check the methods defined in JSON, you will notice that only one method exists, and it does not have ::Function as its first argument:

julia> methods(JSON.parsefile)
# 1 method for generic function "parsefile":
[1] parsefile(filename::AbstractString; dicttype, inttype, null, allownan, use_mmap) in JSON.Parser at /home/alain/.julia/packages/JSON/3rsiS/src/Parser.jl:518

The try pitfall

When you get unexpected behaviour like this, I highly recommend commenting out the try/catch/end block to see what is happening. Normally, Julia’s exception system would have shown you a helpful error message, but it gets suppressed by your try/catch block:

ERROR: MethodError: no method matching parsefile(::var"#7#8", ::String)
Stacktrace:
 [1] top-level scope at REPL[8]:1

Now that you understand how function()-do statements work, you can see that Julia cannot find a version of parsefile() that accepts a ::Function as its first argument (even if it displays a message with the somewhat cryptic ::var"#7#8" type in Julia v1.3.1).

1 Like