Skip to content

Commit 1d5ee59

Browse files
authored
Improve text of showerror for NotAllowedError (#2757)
1 parent 2ecfa90 commit 1d5ee59

File tree

3 files changed

+90
-74
lines changed

3 files changed

+90
-74
lines changed

src/error.jl

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,40 @@ form).
5151
function operation_name end
5252

5353
function Base.showerror(io::IO, err::NotAllowedError)
54-
print(io, typeof(err), ": ", operation_name(err), " cannot be performed")
54+
println(io, typeof(err), ":\n")
55+
println(io, "## Cause\n")
56+
print(io, operation_name(err), " cannot be performed")
5557
m = message(err)
56-
if Base.isempty(m)
57-
print(io, ".")
58+
if isempty(m)
59+
println(io)
5860
else
59-
print(io, ": ", m)
61+
println(io, " because:\n\n", m)
6062
end
61-
return print(
63+
println(io)
64+
print(
6265
io,
63-
" You may want to use a `CachingOptimizer` in `AUTOMATIC` mode",
64-
" or you may need to call `reset_optimizer` before doing this",
65-
" operation if the `CachingOptimizer` is in `MANUAL` mode.",
66+
"""
67+
## Fixing this error
68+
69+
An `MOI.NotAllowedError` error occurs when you have tried to do something that
70+
is not implemented by the solver.
71+
72+
The most common way to fix this error is to wrap the optimizer in a
73+
`MOI.Utilities.CachingOptimizer`.
74+
75+
For example, if you are using `JuMP.Model` or `JuMP.set_optimizer`, do:
76+
```julia
77+
model = JuMP.Model(optimizer; with_cache_type = Float64)
78+
model = JuMP.GenericModel{T}(optimizer; with_cache_type = T)
79+
JuMP.set_optimizer(model, optimizer; with_cache_type = Float64)
80+
```
81+
Similarly, if you are using `MOI.instantiate`, do:
82+
```julia
83+
model = MOI.instantiate(optimizer; with_cache_type = Float64)
84+
```
85+
""",
6686
)
87+
return
6788
end
6889

6990
"""

test/General/attributes.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ function test_submit_not_allowed()
356356
@test MOI.SubmitNotAllowed(submit) == MOI.SubmitNotAllowed(submit, "")
357357
err = MOI.SubmitNotAllowed(submit, "msg")
358358
contents = sprint(showerror, err)
359-
@test occursin("Submitting $submit cannot be performed: msg", contents)
359+
@test occursin("Submitting $submit cannot be performed", contents)
360+
@test occursin("msg", contents)
360361
return
361362
end
362363

test/General/errors.jl

Lines changed: 59 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ function test_errors_fallback_AddVariableNotAllowed()
2727
try
2828
MOI.add_variable(model)
2929
catch err
30-
@test sprint(showerror, err) ==
31-
"MathOptInterface.AddVariableNotAllowed:" *
32-
" Adding variables cannot be performed. You may want to use a" *
33-
" `CachingOptimizer` in `AUTOMATIC` mode or you may need to call" *
34-
" `reset_optimizer` before doing this operation if the" *
35-
" `CachingOptimizer` is in `MANUAL` mode."
30+
contents = sprint(showerror, err)
31+
@test occursin("$(MOI.AddVariableNotAllowed)", contents)
32+
@test occursin("Adding variables cannot be performed", contents)
33+
@test occursin("## Fixing this error", contents)
3634
end
3735
@test_throws MOI.AddVariableNotAllowed MOI.add_variables(model, 2)
3836
return
@@ -104,13 +102,14 @@ function test_errors_add_constraint()
104102
try
105103
MOI.add_constraint(model, vi, MOI.EqualTo(0.0))
106104
catch err
107-
@test sprint(showerror, err) ==
108-
"$(MOI.AddConstraintNotAllowed{MOI.VariableIndex,MOI.EqualTo{Float64}}):" *
109-
" Adding `$MOI.VariableIndex`-in-`$MOI.EqualTo{Float64}`" *
110-
" constraints cannot be performed. You may want to use a" *
111-
" `CachingOptimizer` in `AUTOMATIC` mode or you may need to call" *
112-
" `reset_optimizer` before doing this operation if the" *
113-
" `CachingOptimizer` is in `MANUAL` mode."
105+
contents = sprint(showerror, err)
106+
F, S = MOI.VariableIndex, MOI.EqualTo{Float64}
107+
@test occursin("$(MOI.AddConstraintNotAllowed{F,S})", contents)
108+
@test occursin(
109+
"Adding `$F`-in-`$S` constraints cannot be performed",
110+
contents,
111+
)
112+
@test occursin("## Fixing this error", contents)
114113
end
115114
@test_throws(
116115
MOI.AddConstraintNotAllowed,
@@ -139,23 +138,19 @@ function test_errors_DeleteNotAllowed()
139138
try
140139
MOI.delete(model, vi)
141140
catch err
142-
@test sprint(showerror, err) ==
143-
"$(MOI.DeleteNotAllowed{typeof(vi)}): Deleting the index $vi " *
144-
"cannot be performed. You may want to use a `CachingOptimizer` " *
145-
"in `AUTOMATIC` mode or you may need to call `reset_optimizer` " *
146-
"before doing this operation if the `CachingOptimizer` is in " *
147-
"`MANUAL` mode."
141+
contents = sprint(showerror, err)
142+
@test occursin("$(MOI.DeleteNotAllowed{typeof(vi)})", contents)
143+
@test occursin("Deleting the index $vi cannot be performed", contents)
144+
@test occursin("## Fixing this error", contents)
148145
end
149146
@test_throws MOI.DeleteNotAllowed{typeof(ci)} MOI.delete(model, ci)
150147
try
151148
MOI.delete(model, ci)
152149
catch err
153-
@test sprint(showerror, err) ==
154-
"$(MOI.DeleteNotAllowed{typeof(ci)}): Deleting the index $ci " *
155-
"cannot be performed. You may want to use a `CachingOptimizer` " *
156-
"in `AUTOMATIC` mode or you may need to call `reset_optimizer` " *
157-
"before doing this operation if the `CachingOptimizer` is in " *
158-
"`MANUAL` mode."
150+
contents = sprint(showerror, err)
151+
@test occursin("$(MOI.DeleteNotAllowed{typeof(ci)})", contents)
152+
@test occursin("Deleting the index $ci cannot be performed", contents)
153+
@test occursin("## Fixing this error", contents)
159154
end
160155
return
161156
end
@@ -244,14 +239,14 @@ function test_errors_ModifyNotAllowed_constraint()
244239
change = MOI.ScalarConstantChange(1.0)
245240
err = MOI.ModifyConstraintNotAllowed(ci, change)
246241
@test_throws err MOI.modify(model, ci, change)
247-
@test sprint(showerror, err) ==
248-
"$(MOI.ModifyConstraintNotAllowed{MOI.VariableIndex,MOI.EqualTo{Float64},MOI.ScalarConstantChange{Float64}}):" *
249-
" Modifying the constraints $(MOI.ConstraintIndex{MOI.VariableIndex,MOI.EqualTo{Float64}}(1))" *
250-
" with MathOptInterface.ScalarConstantChange{Float64}(1.0) cannot" *
251-
" be performed. You may want to use a `CachingOptimizer` in" *
252-
" `AUTOMATIC` mode or you may need to call `reset_optimizer`" *
253-
" before doing this operation if the `CachingOptimizer` is in" *
254-
" `MANUAL` mode."
242+
contents = sprint(showerror, err)
243+
@test occursin("$(typeof(err)):", contents)
244+
@test occursin(
245+
"Modifying the constraints $ci with $change cannot be performed",
246+
contents,
247+
)
248+
@test occursin("## Fixing this error", contents)
249+
return
255250
end
256251

257252
function test_errors_ModifyNotAllowed_objective()
@@ -260,13 +255,14 @@ function test_errors_ModifyNotAllowed_objective()
260255
attr = MOI.ObjectiveFunction{MOI.VariableIndex}()
261256
err = MOI.ModifyObjectiveNotAllowed(change)
262257
@test_throws err MOI.modify(model, attr, change)
263-
@test sprint(showerror, err) ==
264-
"$(MOI.ModifyObjectiveNotAllowed{MOI.ScalarConstantChange{Float64}}):" *
265-
" Modifying the objective function with $(MOI.ScalarConstantChange{Float64}(1.0))" *
266-
" cannot be performed. You may want to use a `CachingOptimizer`" *
267-
" in `AUTOMATIC` mode or you may need to call `reset_optimizer`" *
268-
" before doing this operation if the `CachingOptimizer` is in" *
269-
" `MANUAL` mode."
258+
contents = sprint(showerror, err)
259+
@test occursin("$(typeof(err)):", contents)
260+
@test occursin(
261+
"Modifying the objective function with $change cannot be performed",
262+
contents,
263+
)
264+
@test occursin("## Fixing this error", contents)
265+
return
270266
end
271267

272268
function test_errors_show_SetAttributeNotAllowed()
@@ -276,26 +272,22 @@ function test_errors_show_SetAttributeNotAllowed()
276272
@test sprint(showerror, MOI.UnsupportedAttribute(MOI.Name(), "Message")) ==
277273
"$MOI.UnsupportedAttribute{$MOI.Name}:" *
278274
" Attribute $MOI.Name() is not supported by the model: Message"
279-
@test sprint(showerror, MOI.SetAttributeNotAllowed(MOI.Name())) ==
280-
"$MOI.SetAttributeNotAllowed{$MOI.Name}:" *
281-
" Setting attribute $MOI.Name() cannot be performed. You may want to use" *
282-
" a `CachingOptimizer` in `AUTOMATIC` mode or you may need to call" *
283-
" `reset_optimizer` before doing this operation if the" *
284-
" `CachingOptimizer` is in `MANUAL` mode."
285-
@test sprint(
286-
showerror,
287-
MOI.SetAttributeNotAllowed(MOI.Name(), "Message"),
288-
) ==
289-
"$MOI.SetAttributeNotAllowed{$MOI.Name}:" *
290-
" Setting attribute $MOI.Name() cannot be performed: Message You may want" *
291-
" to use a `CachingOptimizer` in `AUTOMATIC` mode or you may need to call" *
292-
" `reset_optimizer` before doing this operation if the `CachingOptimizer`" *
293-
" is in `MANUAL` mode." ==
294-
"$MOI.SetAttributeNotAllowed{$MOI.Name}:" *
295-
" Setting attribute $MOI.Name() cannot be performed: Message You may want" *
296-
" to use a `CachingOptimizer` in `AUTOMATIC` mode or you may need to call" *
297-
" `reset_optimizer` before doing this operation if the `CachingOptimizer`" *
298-
" is in `MANUAL` mode."
275+
contents = sprint(showerror, MOI.SetAttributeNotAllowed(MOI.Name()))
276+
@test occursin("$MOI.SetAttributeNotAllowed{$MOI.Name}:", contents)
277+
@test occursin(
278+
"Setting attribute $(MOI.Name()) cannot be performed",
279+
contents,
280+
)
281+
@test occursin("## Fixing this error", contents)
282+
err = MOI.SetAttributeNotAllowed(MOI.Name(), "Message")
283+
contents = sprint(showerror, err)
284+
@test occursin("$(typeof(err))", contents)
285+
@test occursin("Message", contents)
286+
@test occursin(
287+
"Setting attribute $(MOI.Name()) cannot be performed",
288+
contents,
289+
)
290+
@test occursin("## Fixing this error", contents)
299291
return
300292
end
301293

@@ -352,11 +344,13 @@ function test_get_fallback_error()
352344
MOI.get(model, MOI.SolveTimeSec()),
353345
)
354346
err = MOI.GetAttributeNotAllowed(MOI.SolveTimeSec(), "")
355-
@test sprint(showerror, err) ==
356-
"$(typeof(err)): Getting attribute $(MOI.SolveTimeSec()) cannot be " *
357-
"performed. You may want to use a `CachingOptimizer` in " *
358-
"`AUTOMATIC` mode or you may need to call `reset_optimizer` before " *
359-
"doing this operation if the `CachingOptimizer` is in `MANUAL` mode."
347+
contents = sprint(showerror, err)
348+
@test occursin("$(typeof(err)):", contents)
349+
@test occursin(
350+
"Getting attribute $(MOI.SolveTimeSec()) cannot be performed",
351+
contents,
352+
)
353+
@test occursin("## Fixing this error", contents)
360354
return
361355
end
362356

0 commit comments

Comments
 (0)