Add exception handling to the solver creation call
This is a very targeted addition, which can be generalized. It makes the following changes: 1. In the solver creation call of the Gurobi interface, i.e. the constructor `GurobiInterface::GurobiInterface`, the GLOG severity level is reduced to `DFATAL`, which becomes `ERROR` in production. This means errors in calls to `GRBloadenv` no longer automatically kill the process as a side effect. 2. An `std::runtime_error` exception is raised with the return code and the error message from GRBloadenv. This replaces the functionality of exiting the process when this error is unhandled. Additionally, it enables alternate handling by the caller. 3. In the linear solver SWIG wrapper, exception wrapping is turned on specifically for the `MPSolver::MPSolver` constructor call and the `std::runtime_error` that may now occur there. This exception is re-raised as the corresponding RuntimeError in the target language. Addresses issue #699.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
@@ -176,10 +177,13 @@ class GurobiInterface : public MPSolverInterface {
|
||||
// Creates a LP/MIP instance with the specified name and minimization objective.
|
||||
GurobiInterface::GurobiInterface(MPSolver* const solver, bool mip)
|
||||
: MPSolverInterface(solver), model_(nullptr), env_(nullptr), mip_(mip) {
|
||||
if (GRBloadenv(&env_, nullptr) != 0 || env_ == nullptr) {
|
||||
LOG(FATAL) << "Error: could not create environment: "
|
||||
<< GRBgeterrormsg(env_);
|
||||
}
|
||||
|
||||
int ret = GRBloadenv(&env_, nullptr);
|
||||
if (ret != 0 || env_ == nullptr) {
|
||||
std::string err_msg = GRBgeterrormsg(env_);
|
||||
LOG(DFATAL) << "Error: could not create environment: " << err_msg;
|
||||
throw std::runtime_error(std::to_string(ret) + ", " + err_msg);
|
||||
}
|
||||
|
||||
CheckedGurobiCall(GRBnewmodel(env_, &model_, solver_->name_.c_str(),
|
||||
0, // numvars
|
||||
|
||||
@@ -73,6 +73,17 @@ from ortools.linear_solver.linear_solver_natural_api import VariableExpr
|
||||
} // %pythoncode
|
||||
}
|
||||
|
||||
// Catch runtime exceptions in class methods
|
||||
%extend MPSolver {
|
||||
%exception MPSolver {
|
||||
try {
|
||||
$action
|
||||
} catch ( std::runtime_error& e ) {
|
||||
SWIG_exception(SWIG_RuntimeError, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%extend MPSolver {
|
||||
// Change a (bool, std::string*) outputs to a python std::string (empty if bool=false).
|
||||
std::string ExportModelAsLpFormat(bool obfuscated) {
|
||||
|
||||
Reference in New Issue
Block a user