-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support catching specific exception types #23418
Comments
Duplicate of #1075. If we do this, it could be implemented entirely in the front end. First the parser would have to be modified to accept multiple catch blocks, then these would be lowered into |
What if instead of try
foo()
catch e -> e isa NetworkError
...
catch e -> e isa HTTPError && e.code == 404
...
end try
foo()
catch e if e isa NetworkError
...
catch e if e isa HTTPError && e.code == 404
...
end Catching on a Bool function (or expression) is more flexible than catching on types, and not very much more verbose for cases where the expression is just Also can we have a [updated: changed |
Related #15906 |
The problem in your example @samoconnor is you're missing |
@quinnj thanks for spotting |
@JeffBezanson, @StefanKarpinski Here's another possibility with a smaller change and the same intention of reducing unintended over-catching.... What if julia> try
foo()
catch e
println("Whoops foo() said: $e")
end
Whoops foo() said: UndefVarError(:foo)
ERROR: UndefVarError: foo not defined vs julia> try
foo()
catch e
println("Whoops foo() said: $e")
delete!(e)
end
Whoops foo() said: UndefVarError(:foo) The example above would become: try
foo()
catch e
if e isa NetworkError
...
delete!(e)
elseif e isa HTTPError && e.code == 404
...
delete!(e)
end
end With this feature you might change #15906 to be "Undeleteable exceptions"... try
foo()
catch e
delete!(e)
end
ERROR: OutOfMemoryError is not deletable. (Maybe |
@quinnj I feel pretty strongly that catch-by-type is a half-way solution, and that we should be able to do better than what Java did 20 years ago. |
But I feel like you're just hijacking this feature request, which was intended to be minimal and hopefully easily accepted. You're basically just reproposing #15906, which you can and should discuss on those threads. I'd rather we at least do the simple thing first, which, again, should hopefully be easily accepted by everyone before we try re-inventing error-handling. Don't get me wrong, grand visions and creative functionality have their place, but I'm just trying to push for a basic language feature that most other languages support. |
Sorry @quinnj, I didn't mean to make you feel like your request was hijacked. |
How is progress on this subject? |
Yeah, this is crazy that such a feature is not already supported... |
I have created this workaround in the mean time (will be available after the 3 day package registration period): |
Not yet available? 👀👀 |
Y'all are commenting as though it is decided that this should be done and it simply hasn't been implemented. That is not the case. It is unclear that we want this. That said, I've come to favor it because I realized at some point that it doesn't actually clash with the "chain of custody" idea I proposed long ago since they can be distinguished by whether there are |
Just for reference: not having found this issue here, I proposed the exact same modification to the try-catch syntax on discourse. Some thoughts and ideas could crop up there as well. I'm definitely in favor of this change. |
I came up with a macro that makes it easier to create an anonymous error handler using multiple dispatch rather than building an if/else statement. https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/22?u=mkitti macro error_dispatch(e)
_error_dispatch(e)
end
function _error_dispatch(ex)
catch_block = ex.args[3]
exception = ex.args[2]
catch_func = gensym(:catch)
# map anonymous functions to methods of a gensym named function
catch_block.args = map(catch_block.args) do cex
if cex isa Expr && cex.head == :(->)
_anon_to_named_func(catch_func, cex)
else
cex
end
end
# call named function
push!(catch_block.args, :($catch_func($exception)))
esc(ex)
end
# convert anonymous functions to method of named function
function _anon_to_named_func(name::Symbol, anon::Expr)
@assert(anon.head == :(->))
func_args = anon.args[1]
func_body = anon.args[2]
quote
$name($func_args) = $func_body
end
end The usage looks like this: julia> function foo(g)
@error_dispatch try
g()
catch e
e::AssertionError -> println("Hello. I got an AssertionError!")
e::InexactError -> println("Hola. ¡Recibí un InexactError!")
end
end
foo (generic function with 1 method)
julia> foo(()->@assert(false))
Hello. I got an AssertionError!
julia> foo(()->Int(5.2))
Hola. ¡Recibí un InexactError! The macro expansion is as follows. julia> @macroexpand @error_dispatch try
g()
catch e
e::AssertionError -> println("Hello. I got an AssertionError!")
e::InexactError -> println("Hola. ¡Recibí un IneaxctError!")
e -> println("Unexpected Error")
end
:(try
#= REPL[90]:2 =#
g()
catch e
#= REPL[90]:4 =#
begin
#= REPL[74]:6 =#
var"##catch#315"(e::AssertionError) = begin
#= REPL[74]:6 =#
begin
#= REPL[90]:4 =#
println("Hello. I got an AssertionError!")
end
end
end
#= REPL[90]:5 =#
begin
#= REPL[74]:6 =#
var"##catch#315"(e::InexactError) = begin
#= REPL[74]:6 =#
begin
#= REPL[90]:5 =#
println("Hola. ¡Recibí un IneaxctError!")
end
end
end
#= REPL[90]:6 =#
begin
#= REPL[74]:6 =#
var"##catch#315"(e) = begin
#= REPL[74]:6 =#
begin
#= REPL[90]:6 =#
println("Unexpected Error")
end
end
end
var"##catch#315"(e)
end) |
A la
I know there have been (hotly debated) grand visions of error-handling laid out in #7026 and #15514, but as far as julia 1.0, I think we should at least support catching specific errors. My latest methodology for error-handling goes something like:
The only issue w/ this approach is I end up w/ code like:
which is decidedly less pleasant. I feel like having just a little extra syntax could go a long way to making error-handling feel a little more grown up in julia.
Any idea on how hard this would be? Where to start looking to implement?
The text was updated successfully, but these errors were encountered: