Skip to content

Commit 1d114d3

Browse files
committed
Add error hints
1 parent daad441 commit 1d114d3

File tree

6 files changed

+201
-0
lines changed

6 files changed

+201
-0
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ The default cache size for regridded fields in `DataHandler` was reduced from
7373
128 to 2, reducing the memory footprint. You can pass the `cache_max_size`
7474
keyword argument to control this value.
7575

76+
#### Error hints
77+
78+
When using a function that depends on loading another package, the error now tells the user
79+
which package should be loaded if the package has not been loaded already.
80+
7681
v0.1.19
7782
------
7883

src/DataHandling.jl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,61 @@ function time_to_date end
6161

6262
function date_to_time end
6363

64+
extension_fns = [
65+
:ClimaCore => [
66+
:DataHandler,
67+
:available_times,
68+
:available_dates,
69+
:previous_time,
70+
:next_time,
71+
:regridded_snapshot,
72+
:regridded_snapshot!,
73+
:dt,
74+
:time_to_date,
75+
:date_to_time,
76+
],
77+
:NCDatasets => [
78+
:DataHandler,
79+
:available_times,
80+
:available_dates,
81+
:previous_time,
82+
:next_time,
83+
:regridded_snapshot,
84+
:regridded_snapshot!,
85+
:dt,
86+
:time_to_date,
87+
:date_to_time,
88+
],
89+
]
90+
91+
"""
92+
is_pkg_loaded(pkg::Symbol)
93+
94+
Check if `pkg` is loaded or not.
95+
"""
96+
function is_pkg_loaded(pkg::Symbol)
97+
return any(k -> Symbol(k.name) == pkg, keys(Base.loaded_modules))
98+
end
99+
100+
function __init__()
101+
# Register error hint if a package is not loaded
102+
if isdefined(Base.Experimental, :register_error_hint)
103+
Base.Experimental.register_error_hint(
104+
MethodError,
105+
) do io, exc, _argtypes, _kwargs
106+
for (pkg, fns) in extension_fns
107+
if Symbol(exc.f) in fns && !is_pkg_loaded(pkg)
108+
print(io, "\nImport $pkg to enable `$(exc.f)`.";)
109+
end
110+
end
111+
if Symbol(exc.f) == :DataHandler
112+
print(
113+
io,
114+
"\nYou might also need a regridder to use `$(exc.f)`.",
115+
)
116+
end
117+
end
118+
end
119+
end
120+
64121
end

src/FileReaders.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,39 @@ function available_dates end
2323

2424
function close_all_ncfiles end
2525

26+
extension_fns = [
27+
:NCDatasets => [
28+
:NCFileReader,
29+
:read,
30+
:read!,
31+
:available_dates,
32+
:close_all_ncfiles,
33+
:close,
34+
],
35+
]
36+
37+
"""
38+
is_pkg_loaded(pkg::Symbol)
39+
40+
Check if `pkg` is loaded or not.
41+
"""
42+
function is_pkg_loaded(pkg::Symbol)
43+
return any(k -> Symbol(k.name) == pkg, keys(Base.loaded_modules))
44+
end
45+
46+
function __init__()
47+
# Register error hint if a package is not loaded
48+
if isdefined(Base.Experimental, :register_error_hint)
49+
Base.Experimental.register_error_hint(
50+
MethodError,
51+
) do io, exc, _argtypes, _kwargs
52+
for (pkg, fns) in extension_fns
53+
if Symbol(exc.f) in fns && !is_pkg_loaded(pkg)
54+
print(io, "\nImport $pkg to enable `$(exc.f)`.";)
55+
end
56+
end
57+
end
58+
end
59+
end
60+
2661
end

src/Regridders.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,34 @@ function default_regridder_type()
5555
return regridder_type
5656
end
5757

58+
extension_fns = [
59+
:ClimaCoreTempestRemap => [:TempestRegridder, :regrid],
60+
:ClimaCore => [:InterpolationsRegridder, :regrid],
61+
:Interpolations => [:InterpolationsRegridder, :regrid],
62+
]
63+
64+
"""
65+
is_pkg_loaded(pkg::Symbol)
66+
67+
Check if `pkg` is loaded or not.
68+
"""
69+
function is_pkg_loaded(pkg::Symbol)
70+
return any(k -> Symbol(k.name) == pkg, keys(Base.loaded_modules))
71+
end
72+
73+
function __init__()
74+
# Register error hint if a package is not loaded
75+
if isdefined(Base.Experimental, :register_error_hint)
76+
Base.Experimental.register_error_hint(
77+
MethodError,
78+
) do io, exc, _argtypes, _kwargs
79+
for (pkg, fns) in extension_fns
80+
if Symbol(exc.f) in fns && !is_pkg_loaded(pkg)
81+
print(io, "\nImport $pkg to enable `$(exc.f)`.";)
82+
end
83+
end
84+
end
85+
end
86+
end
87+
5888
end

src/SpaceVaryingInputs.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,38 @@ module SpaceVaryingInputs
1818

1919
function SpaceVaryingInput end
2020

21+
extension_fns =
22+
[:ClimaCore => [:SpaceVaryingInput], :NCDatasets => [:SpaceVaryingInput]]
23+
24+
"""
25+
is_pkg_loaded(pkg::Symbol)
26+
27+
Check if `pkg` is loaded or not.
28+
"""
29+
function is_pkg_loaded(pkg::Symbol)
30+
return any(k -> Symbol(k.name) == pkg, keys(Base.loaded_modules))
31+
end
32+
33+
function __init__()
34+
# Register error hint if a package is not loaded
35+
if isdefined(Base.Experimental, :register_error_hint)
36+
Base.Experimental.register_error_hint(
37+
MethodError,
38+
) do io, exc, _argtypes, _kwargs
39+
for (pkg, fns) in extension_fns
40+
if Symbol(exc.f) in fns && !is_pkg_loaded(pkg)
41+
print(io, "\nImport $pkg to enable `$(exc.f)`.";)
42+
end
43+
if Symbol(exc.f) == :SpaceVaryingInput
44+
print(
45+
io,
46+
"\nYou might also need a regridder to use `$(exc.f)`.";
47+
)
48+
end
49+
end
50+
end
51+
end
52+
end
53+
54+
2155
end

src/TimeVaryingInputs.jl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,44 @@ struct LinearPeriodFillingInterpolation{
312312
end
313313
end
314314

315+
extension_fns = [
316+
:ClimaCore => [:TimeVaryingInput, :evaluate!],
317+
:NCDatasets => [:TimeVaryingInput, :evaluate!],
318+
:CUDA => [:TimeVaryingInput, :evaluate!],
319+
]
320+
321+
"""
322+
is_pkg_loaded(pkg::Symbol)
323+
324+
Check if `pkg` is loaded or not.
325+
"""
326+
function is_pkg_loaded(pkg::Symbol)
327+
return any(k -> Symbol(k.name) == pkg, keys(Base.loaded_modules))
328+
end
329+
330+
function __init__()
331+
# Register error hint if a package is not loaded
332+
if isdefined(Base.Experimental, :register_error_hint)
333+
Base.Experimental.register_error_hint(
334+
MethodError,
335+
) do io, exc, _argtypes, _kwargs
336+
for (pkg, fns) in extension_fns
337+
if Symbol(exc.f) in fns && !is_pkg_loaded(pkg)
338+
if pkg == :CUDA
339+
print(io, "\nIf you are using a GPU, import CUDA.")
340+
else
341+
print(io, "\nImport $pkg to enable `$(exc.f)`.";)
342+
end
343+
end
344+
end
345+
if Symbol(exc.f) == :TimeVaryingInput
346+
print(
347+
io,
348+
"\nYou might also need a regridder to use `$(exc.f)`.";
349+
)
350+
end
351+
end
352+
end
353+
end
354+
315355
end

0 commit comments

Comments
 (0)