Skip to content
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

Extensible help system for displaying MethodErrors #24299

Closed
wants to merge 1 commit into from

Conversation

mbauman
Copy link
Member

@mbauman mbauman commented Oct 23, 2017

Fixes #7512. This adds a hook for developers to add custom help messages when
MethodErrors get displayed. Feel free to bikeshed the naming of this method.

This is particularly helpful in cases of intentionally unimplemented methods.
I've also restructured the existing help messages in terms of this new system,
using the info command to display them (and a few extra messages, too):

julia> Int("1")
ERROR: MethodError: no method matching convert(::Type{Int64}, ::String)
INFO: Cannot `convert` an object of type String to an object of type Int64.
INFO: This may have arisen from a call to the constructor Int64(...), since type constructors fall back to convert methods.

Stacktrace:
 [1] Int64(::String) at ./sysimg.jl:114

julia> min([1,2,3])
ERROR: MethodError: no method matching min(::Array{Int64,1})
INFO: Use minimum() to find the smallest element of an array.

Closest candidates are:
  min(::AbstractArray{T1<:Real,N} where N, ::Real) where T1<:Real at deprecated.jl:55
  min(::AbstractArray{T1<:Real,N} where N, ::AbstractArray{T2<:Real,N} where N) where {T1<:Real, T2<:Real} at deprecated.jl:55
  min(::Any, ::Any) at operators.jl:404
  ...

julia> [1,2,3](1)
ERROR: MethodError: no method matching (::Array{Int64,1})(::Int64)
INFO: Use square brackets [] for indexing into arrays.

julia> [x for x in nothing]
ERROR: MethodError: no method matching start(::Void)
INFO: Objects of type Void are not iterable.

Closest candidates are:
  start(::SimpleVector) at essentials.jl:534
  start(::Base.MethodList) at reflection.jl:659
  start(::ExponentialBackOff) at error.jl:147
  ...
Stacktrace:
 [1] collect(::Base.Generator{Void,getfield(Main, Symbol("##1#2"))}) at ./array.jl:656

Feel free to bikeshed the name (no_method_error_help).

This is an old branch/idea that I had totally forgotten about; I was reminded by #24284, which would be very trivial in this setup.

Fixes #7512.  This adds a hook for developers to add custom help messages when
`MethodError`s get displayed.  Feel free to bikeshed the naming of this method.

This is particularly helpful in cases of intentionally unimplemented methods.
I've also restructured the existing help messages in terms of this new system,
using the `info` command to display them:

```
julia> Int("1")
ERROR: MethodError: no method matching convert(::Type{Int64}, ::String)
INFO: Cannot `convert` an object of type String to an object of type Int64.
INFO: This may have arisen from a call to the constructor Int64(...), since type constructors fall back to convert methods.

Stacktrace:
 [1] Int64(::String) at ./sysimg.jl:114

julia> min([1,2,3])
ERROR: MethodError: no method matching min(::Array{Int64,1})
INFO: Use minimum() to find the smallest element of an array.

Closest candidates are:
  min(::AbstractArray{T1<:Real,N} where N, ::Real) where T1<:Real at deprecated.jl:55
  min(::AbstractArray{T1<:Real,N} where N, ::AbstractArray{T2<:Real,N} where N) where {T1<:Real, T2<:Real} at deprecated.jl:55
  min(::Any, ::Any) at operators.jl:404
  ...

julia> [1,2,3](1)
ERROR: MethodError: no method matching (::Array{Int64,1})(::Int64)
INFO: Use square brackets [] for indexing into arrays.
```

Feel free to bikeshed the name (`no_method_error_help`).
@kshyatt kshyatt added display and printing Aesthetics and correctness of printed representations of objects. error handling Handling of exceptions by Julia or the user labels Oct 23, 2017
@ararslan ararslan added needs news A NEWS entry is required for this change needs tests Unit tests are required for this change labels Oct 24, 2017
@mauro3
Copy link
Contributor

mauro3 commented Dec 9, 2017

This is great! Bike-shedding the name, maybe methoderror_help to mirror MethodError. Also, I think this printing makes equally sense in non-interactive use.

Interface-wise it would be nicer if instead of

no_method_error_help(io, ::AbstractArray, args...) = info(io, "Use square brackets [] for indexing into arrays.")

this was possible:

(::AbstractArray)(args...) = throw(MethodError( "Use square brackets [] for indexing into arrays."))

whilst still retaining method_exists(AbstractArray, (Vararg,))==false. (Although that also runs into #14919). However, I suspect that this is much harder, let's go with this.

@mbauman
Copy link
Member Author

mbauman commented Mar 20, 2020

Implemented in #35094

@mbauman mbauman closed this Mar 20, 2020
@mbauman mbauman deleted the mb/extensible-method-error branch March 20, 2020 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects. error handling Handling of exceptions by Julia or the user needs news A NEWS entry is required for this change needs tests Unit tests are required for this change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

More helpful MethodErrors for deliberately unimplemented methods
4 participants