Skip to content

[PEP] Consistent Exceptions/Errors for Solvers #3775

@mrmundt

Description

@mrmundt

Summary

We have wanted to create a consistent approach to exceptions/errors for solvers for a while. With the impending changes to solver interfaces well underway, we desperately need to actually create this approach.

Description

Here is my initial proposed solution:

  1. Create a set of "standard" exceptions that are generally true across all solvers that live either in pyomo.contrib.solver.common.errors or pyomo.common.errors (I have a preference for the former while we tweak with them, and then we can graduate them to the latter)
  2. Each solver, if they have specific exceptions, would be expected to implement them in their own base file / directory
  3. Exceptions should be used as minimally as possible - instead, lean towards logging for situations that are "acceptable but not necessarily ideal"
  4. Create a standard set of situations in which we would expect exceptions to occur. For example:
    • Attempting to load a solution when there is no solution
    • Attempting to use a feature that isn't defined / supported

We also desperately need to fix the message that Pyomo returns by default:



Serial Solver Interfaces
------------------------
The serial manager supports the following solver interfaces:

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.10.18/x64/bin/pyomo", line 7, in <module>
    sys.exit(main_console_script())
  File "/home/runner/work/pyomo/pyomo/pyomo/scripting/pyomo_main.py", line 104, in main_console_script
    ans = main()
  File "/home/runner/work/pyomo/pyomo/pyomo/scripting/pyomo_main.py", line 94, in main
    retval = _options.func(_options)
  File "/home/runner/work/pyomo/pyomo/pyomo/scripting/driver_help.py", line 455, in help_exec
    help_solvers()
  File "/home/runner/work/pyomo/pyomo/pyomo/scripting/driver_help.py", line 271, in help_solvers
    elif getattr(opt, "_metasolver", False):
  File "/home/runner/work/pyomo/pyomo/pyomo/opt/base/solvers.py", line 126, in __getattr__
    self._solver_error(attr)
  File "/home/runner/work/pyomo/pyomo/pyomo/opt/base/solvers.py", line 129, in _solver_error
    raise RuntimeError(
RuntimeError: Attempting to use an unavailable solver.

The SolverFactory was unable to create the solver "cuopt"
and returned an UnknownSolver object.  This error is raised at the point
where the UnknownSolver object was used as if it were valid (by calling
method "_metasolver").

The original solver was created with the following parameters:
	type: cuopt
	_args: ()
	options: {}

This isn't a remotely helpful message. Why is it unavailable? Does a user care about an UnknownSolver object? No, no they don't.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions