Error Handling¶
TQrouting raises its own exception hierarchy for everything related to your
problem, license, or the solver — all of it inherits from TQRoutingError,
so you can catch broadly or narrowly.
Plain argument misuse follows the standard Python convention instead:
passing an invalid value to solve() (a negative time_limit, a negative
objective weight, an unknown soft_constraints name) raises a built-in
ValueError; an unknown keyword, or a value of the wrong type (a
string for time_limit, a bool for nb_threads), raises a TypeError. These are
programming errors — fix the call site rather than catching them at runtime;
an except TQRoutingError handler does not catch them.
Exception Hierarchy¶
TQRoutingError (base)
├── ValidationError
├── SolverError
├── LicenseError
├── UnsupportedPlatformError
└── MatrixError
├── OSRMError
├── GoogleMapsError
└── OSRMLocalManagerError
Catching Errors¶
import tqrouting
router = tqrouting.TQRouter()
try:
solution = router.solve(problem)
except tqrouting.LicenseError as e:
print(f"License problem: {e}")
except tqrouting.ValidationError as e:
print(f"Invalid input: {e}")
except tqrouting.SolverError as e:
print(f"Solver failed: {e}")
print(f"Details: {e.details}")
except tqrouting.TQRoutingError as e:
print(f"Unexpected error: {e}")
A ValueError/TypeError escaping this block means the call itself is
wrong (bad argument value or name) — correct the code instead of widening
the handler.
Exception Reference¶
TQRoutingError¶
Base class for all TQrouting exceptions. Catch this to handle any library error:
try:
solution = router.solve(problem)
except tqrouting.TQRoutingError as e:
print(f"Something went wrong: {e}")
LicenseError¶
Raised when the license key is missing, invalid, or expired.
Attributes:
| Attribute | Type | Description |
|---|---|---|
expiry_date |
str or None |
The expiration date (if the key is expired) |
try:
solution = router.solve(problem)
except tqrouting.LicenseError as e:
if e.expiry_date:
print(f"License expired on {e.expiry_date}")
else:
print(f"License error: {e}")
Common causes:
- No license key provided (and
TQROUTING_LICENSE_KEYenv var not set) - Key has expired
- Key signature is invalid
UnsupportedPlatformError¶
Raised on the first solve() when no solver engine is bundled for the
current OS/architecture. Supported platforms: linux/amd64,
macos/arm64 (Apple Silicon), windows/amd64 — notably, Intel Macs are
not supported.
try:
solution = router.solve(problem)
except tqrouting.UnsupportedPlatformError as e:
print(e) # names your platform and lists the supported ones
ValidationError¶
Raised when input data fails validation (before solving) or output data fails validation (after solving).
try:
solution = router.solve(problem)
except tqrouting.ValidationError as e:
print(f"Validation failed: {e}")
Common causes:
- No matrix provided (need at least
distance_matrixorduration_matrix) - Matrix has more rows than
max(matrix_id) + 1, or the two matrices differ in size, or two customers share amatrix_id - Time window
start>end, or a negative time window - A negative or malformed
max_duration,max_distance,shift_startorshift_end(e.g.-1,"abc") - A time string that is not
HH:MM:SS(such as"08:00"), or time fields in two formats within one instance (someHH:MM:SSstrings, some numbers) - Single customer load exceeds max vehicle capacity (in either dimension, on 2-D instances)
- A vehicle type without a capacity its customers demand, on an instance where both quantities appear (in demands or in capacities)
- Fleet has no vehicle types
- A custom
idon only some customers (or only some vehicle types), or the sameidtwice within one of the two lists - A
profiton only some customers (prize-collecting covers the whole instance) x/ycoordinates on only some locations
SolverError¶
Raised when the solver fails unexpectedly — an internal error, a crash, or
running out of memory. Valid input should never trigger it: if you see one,
it is most likely a bug in tqrouting. Please report it and attach
e.details, which carries the full diagnostic payload for us to debug.
try:
solution = router.solve(problem)
except tqrouting.SolverError as e:
print(e) # human-readable summary
print(e.details) # diagnostic payload to attach to a bug report
MatrixError¶
Base class for errors from distance matrix providers.
OSRMError¶
Raised when the OSRM service returns an error or is unreachable.
from tqrouting.matrix import OSRMMatrixProvider
provider = OSRMMatrixProvider(base_url="https://router.project-osrm.org")
try:
instance.compute_distance_matrix(provider)
except tqrouting.OSRMError as e:
print(f"OSRM error: {e}")
Common causes:
- OSRM server not running
- Network timeout
- Coordinates outside the loaded map region
GoogleMapsError¶
Raised when the Google Routes API returns an error.
from tqrouting.matrix import GoogleMatrixProvider
provider = GoogleMatrixProvider()
try:
instance.compute_distance_matrix(provider)
except tqrouting.GoogleMapsError as e:
print(f"Google Maps error: {e}")
Common causes:
- Invalid or expired API key
- Quota exceeded
- No route found between coordinates
OSRMLocalManagerError¶
Raised when the local OSRM Docker management fails.
from tqrouting.matrix import OSRMLocalManager
try:
with OSRMLocalManager(region="europe/germany/bayern") as provider:
instance.compute_distance_matrix(provider)
except tqrouting.OSRMLocalManagerError as e:
print(f"OSRM local error: {e}")
Common causes:
- Docker is not running
- Map download failed (network error)
- Preprocessing step failed (disk space, permissions)
- Container failed to start
- Health check timeout
Warnings¶
Some situations are legal but almost always unintended. The SDK emits a
UserWarning instead of failing, so the solve still runs:
| Warning | Trigger | Fix |
|---|---|---|
| No feasible solution | The result violates constraints (solution_status == "Infeasible") |
Relax constraints, mark some as soft, or raise time_limit |
| All customers skipped | Prize-collecting instance where every prize is below its travel cost | Raise profits or profit_weight — prizes are in objective units |
| Times measured on distances | Time-based fields (time_window, service_time, shift_*, max_duration) on an instance without a duration_matrix |
Provide a duration_matrix |
| Distance weight without distance matrix | distance_weight > 0 but no separate distance_matrix |
Provide a distance_matrix for a real duration/distance trade-off |
| Vehicle without capacity | On an instance with a single quantity, customers carry delivery_load / pickup_load (or volume) but a vehicle type has no capacity_load (capacity_volume), so its vehicles carry unlimited load |
Set the capacity, or silence the warning if that vehicle type is meant to be unlimited |
| Inert parameter | penalty_waiting without time windows, profit_weight without profits, or a soft_constraints entry with nothing to soften |
Remove the parameter, or add the data it acts on |
Silence any of them with Python's standard tools once reviewed: