|
42 | 42 | from zabbix_cli.exceptions import ZabbixAPINotAuthorizedError
|
43 | 43 | from zabbix_cli.exceptions import ZabbixAPIRequestError
|
44 | 44 | from zabbix_cli.exceptions import ZabbixAPIResponseParsingError
|
| 45 | +from zabbix_cli.exceptions import ZabbixAPISessionExpired |
45 | 46 | from zabbix_cli.exceptions import ZabbixAPITokenExpiredError
|
46 | 47 | from zabbix_cli.exceptions import ZabbixNotFoundError
|
47 | 48 | from zabbix_cli.pyzabbix import compat
|
@@ -455,29 +456,55 @@ def do_request(
|
455 | 456 | "Zabbix API returned invalid JSON", response=response
|
456 | 457 | ) from e
|
457 | 458 |
|
458 |
| - if resp.error is not None: |
459 |
| - # some errors don't contain 'data': workaround for ZBX-9340 |
460 |
| - if not resp.error.data: |
461 |
| - resp.error.data = "No data" |
462 |
| - |
463 |
| - # TODO: refactor this exc type narrowing to some sort of predicate/dict lookup |
464 |
| - if "API token expired" in resp.error.data: |
465 |
| - cls = ZabbixAPITokenExpiredError |
466 |
| - logger.debug( |
467 |
| - "API token '%s' has expired.", |
468 |
| - f"{self.auth[:8]}...", # Redact most of the token |
469 |
| - ) |
470 |
| - elif "Not authorized" in resp.error.data: |
471 |
| - cls = ZabbixAPINotAuthorizedError |
472 |
| - else: |
473 |
| - cls = ZabbixAPIRequestError |
474 |
| - raise cls( |
475 |
| - f"Error: {resp.error.message}: {resp.error.data}", |
476 |
| - api_response=resp, |
477 |
| - response=response, |
478 |
| - ) |
| 459 | + self._check_response_errors(resp, response, params) |
| 460 | + |
479 | 461 | return resp
|
480 | 462 |
|
| 463 | + def _check_response_errors( |
| 464 | + self, |
| 465 | + resp: ZabbixAPIResponse, |
| 466 | + response: httpx.Response, |
| 467 | + params: ParamsType, |
| 468 | + ) -> None: |
| 469 | + # Nothing to handlde |
| 470 | + if not resp.error: |
| 471 | + return |
| 472 | + |
| 473 | + # some errors don't contain 'data': workaround for ZBX-9340 |
| 474 | + if not resp.error.data: |
| 475 | + resp.error.data = "No data" |
| 476 | + |
| 477 | + msg = f"Error: {resp.error.message} {resp.error.data}" |
| 478 | + |
| 479 | + to_replace = [ |
| 480 | + (self.auth, "<token>"), |
| 481 | + (params.get("token", ""), "<token>"), |
| 482 | + (params.get("password", ""), "<password>"), |
| 483 | + ] |
| 484 | + for replace in to_replace: |
| 485 | + if replace[0]: |
| 486 | + msg = msg.replace(str(replace), replace[1]) |
| 487 | + |
| 488 | + # TODO: refactor this exc type narrowing to some sort of predicate/dict lookup |
| 489 | + msgc = msg.casefold() |
| 490 | + if "api token expired" in msgc: |
| 491 | + cls = ZabbixAPITokenExpiredError |
| 492 | + logger.debug( |
| 493 | + "API token '%s' has expired.", |
| 494 | + f"{self.auth[:8]}...", # Redact most of the token |
| 495 | + ) |
| 496 | + elif "re-login" in msgc: |
| 497 | + cls = ZabbixAPISessionExpired |
| 498 | + elif "not authorized" in msgc: |
| 499 | + cls = ZabbixAPINotAuthorizedError |
| 500 | + else: |
| 501 | + cls = ZabbixAPIRequestError |
| 502 | + raise cls( |
| 503 | + msg, |
| 504 | + api_response=resp, |
| 505 | + response=response, |
| 506 | + ) |
| 507 | + |
481 | 508 | def populate_cache(self) -> None:
|
482 | 509 | """Populates the various caches with data from the Zabbix API."""
|
483 | 510 | # NOTE: Must be manually invoked. Can we do this in a thread?
|
|
0 commit comments