From ea94f8d298d251520ec4b484739a32354b2a463f Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Wed, 8 Oct 2025 06:05:48 -0400 Subject: [PATCH 1/2] Add explicit error for Simple algorithms iterator interface (#712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit addresses issue #712 by adding a clear error message when users attempt to use the iterator interface (init/step!) with Simple algorithms from SimpleNonlinearSolve.jl. Previously, users would get a confusing error about a missing 'force_stop' field when trying to use Simple algorithms with the iterator interface. Now they receive a helpful error message explaining that: - Simple algorithms don't support the iterator interface - They should use full-featured algorithms from NonlinearSolve.jl instead - They can use solve(prob, alg) if they just want to solve the problem Changes: - Added SciMLBase.init override for AbstractSimpleNonlinearSolveAlgorithm that throws a descriptive error message - Added test file to verify error message works correctly - All Simple algorithms (SimpleNewtonRaphson, SimpleBroyden, SimpleTrustRegion, SimpleDFSane, SimpleKlement, SimpleLimitedMemoryBroyden) are covered 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../src/SimpleNonlinearSolve.jl | 23 +++++++++++++ .../test/core/iterator_interface_tests.jl | 33 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl diff --git a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl index 782de6468..bf8685ea9 100644 --- a/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl +++ b/lib/SimpleNonlinearSolve/src/SimpleNonlinearSolve.jl @@ -124,6 +124,29 @@ function simplenonlinearsolve_solve_up( return SciMLBase.__solve(prob, alg, args...; kwargs...) end +# Iterator Interface Error Handling +# Simple algorithms do not support the iterator interface (init/step!) +function SciMLBase.init( + prob::Union{NonlinearProblem, NonlinearLeastSquaresProblem}, + alg::AbstractSimpleNonlinearSolveAlgorithm, args...; kwargs... +) + error(""" + The Simple algorithms from SimpleNonlinearSolve.jl do not support the iterator interface (init/step!). + + The iterator interface is only available for the full-featured algorithms from NonlinearSolve.jl. + + If you need the iterator interface, please use one of the following algorithms instead: + - NewtonRaphson() + - TrustRegion() + - LevenbergMarquardt() + - And other algorithms from NonlinearSolve.jl + + If you want to solve the problem directly, use `solve(prob, alg)` instead of `init(prob, alg)`. + + Algorithm attempted: $(typeof(alg)) + """) +end + @setup_workload begin for T in (Float64,) prob_scalar = NonlinearProblem{false}((u, p) -> u .* u .- p, T(0.1), T(2)) diff --git a/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl b/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl new file mode 100644 index 000000000..c16b84b13 --- /dev/null +++ b/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl @@ -0,0 +1,33 @@ +@testitem "Iterator Interface Error" tags=[:core] begin + using SimpleNonlinearSolve + + # Test that Simple algorithms properly error when used with the iterator interface + f(u, p) = u .* u .- 2.0 + u0 = 1.5 + prob = NonlinearProblem(f, u0) + + # Test with various Simple algorithms + for alg in [SimpleNewtonRaphson(), SimpleBroyden(), SimpleTrustRegion(), + SimpleDFSane(), SimpleKlement(), SimpleLimitedMemoryBroyden()] + @test_throws ErrorException init(prob, alg) + + # Verify the error message contains helpful information + try + init(prob, alg) + @test false # Should not reach here + catch e + msg = sprint(showerror, e) + @test occursin("iterator interface", msg) + @test occursin("Simple algorithms", msg) + @test occursin("NewtonRaphson()", msg) + @test occursin("solve(prob, alg)", msg) + end + end + + # Verify that solve() still works correctly + for alg in [SimpleNewtonRaphson(), SimpleBroyden(), SimpleTrustRegion()] + sol = solve(prob, alg) + @test sol.retcode == ReturnCode.Success + @test abs(sol.u^2 - 2.0) < 1e-6 + end +end From 05c2c7f9f55c700034c4595b038df246df051c0e Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Wed, 8 Oct 2025 07:05:55 -0400 Subject: [PATCH 2/2] Refactor test to use @test_throws instead of try-catch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced try-catch blocks with @test_throws pattern - Simplified error message verification by using err.value - Test is automatically discovered by @run_package_tests in runtests.jl 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../test/core/iterator_interface_tests.jl | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl b/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl index c16b84b13..60aa743e7 100644 --- a/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl +++ b/lib/SimpleNonlinearSolve/test/core/iterator_interface_tests.jl @@ -9,19 +9,15 @@ # Test with various Simple algorithms for alg in [SimpleNewtonRaphson(), SimpleBroyden(), SimpleTrustRegion(), SimpleDFSane(), SimpleKlement(), SimpleLimitedMemoryBroyden()] - @test_throws ErrorException init(prob, alg) + # Test that an error is thrown + err = @test_throws ErrorException init(prob, alg) # Verify the error message contains helpful information - try - init(prob, alg) - @test false # Should not reach here - catch e - msg = sprint(showerror, e) - @test occursin("iterator interface", msg) - @test occursin("Simple algorithms", msg) - @test occursin("NewtonRaphson()", msg) - @test occursin("solve(prob, alg)", msg) - end + msg = sprint(showerror, err.value) + @test occursin("iterator interface", msg) + @test occursin("Simple algorithms", msg) + @test occursin("NewtonRaphson()", msg) + @test occursin("solve(prob, alg)", msg) end # Verify that solve() still works correctly