Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
errors.py
Go to the documentation of this file.
1# Copyright 2010-2024 Google LLC
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14"""Translate C++'s absl::Status errors to Python standard errors.
15
16Here we try to use the standard Python errors we would use if the C++ code was
17instead implemented in Python. This will give Python users a more familiar API.
18"""
19
20import enum
21from typing import Optional, Type
22from ortools.math_opt import rpc_pb2
23
24
25class _StatusCode(enum.Enum):
26 """The C++ absl::Status::code() values."""
27
28 OK = 0
29 CANCELLED = 1
30 UNKNOWN = 2
31 INVALID_ARGUMENT = 3
32 DEADLINE_EXCEEDED = 4
33 NOT_FOUND = 5
34 ALREADY_EXISTS = 6
35 PERMISSION_DENIED = 7
36 UNAUTHENTICATED = 16
37 RESOURCE_EXHAUSTED = 8
38 FAILED_PRECONDITION = 9
39 ABORTED = 10
40 OUT_OF_RANGE = 11
41 UNIMPLEMENTED = 12
42 INTERNAL = 13
43 UNAVAILABLE = 14
44 DATA_LOSS = 15
45
46
47class InternalMathOptError(RuntimeError):
48 """Some MathOpt internal error.
49
50 This error is usually raised because of a bug in MathOpt or one of the solver
51 library it wraps.
52 """
53
54
56 status_proto: rpc_pb2.StatusProto,
57) -> Optional[Exception]:
58 """Returns the Python exception that best match the input absl::Status.
59
60 There are some Status that we expect the MathOpt code to return, for those the
61 matching exceptions are:
62 - InvalidArgument: ValueError
63 - FailedPrecondition: AssertionError
64 - Unimplemented: NotImplementedError
65 - Internal: InternalMathOptError
66
67 Other Status's are not used by MathOpt, if they are seen a
68 InternalMathOptError is raised (as if the Status was Internal) and the error
69 message contains the unexpected code.
70
71 Args:
72 status_proto: The input proto to convert to an exception.
73
74 Returns:
75 The corresponding exception. None if the input status is OK.
76 """
77 try:
78 code = _StatusCode(status_proto.code)
79 except ValueError:
80 return InternalMathOptError(
81 f"unknown C++ error (code = {status_proto.code}):"
82 f" {status_proto.message}"
83 )
84
85 if code == _StatusCode.OK:
86 return None
87
88 # For expected errors we compute the corresponding class.
89 error_type: Optional[Type[Exception]] = None
90 if code == _StatusCode.INVALID_ARGUMENT:
91 error_type = ValueError
92 if code == _StatusCode.FAILED_PRECONDITION:
93 error_type = AssertionError
94 if code == _StatusCode.UNIMPLEMENTED:
95 error_type = NotImplementedError
96 if code == _StatusCode.INTERNAL:
97 error_type = InternalMathOptError
98
99 if error_type is not None:
100 return error_type(f"{status_proto.message} (was C++ {code.name})")
101
102 return InternalMathOptError(
103 f"unexpected C++ error {code.name}: {status_proto.message}"
104 )
Optional[Exception] status_proto_to_exception(rpc_pb2.StatusProto status_proto)
Definition errors.py:57