From 10dec6ea94e16f569e24b4e1ab0138eb58a7e4e5 Mon Sep 17 00:00:00 2001 From: mariadb-AlanMologorsky Date: Fri, 4 Apr 2025 15:08:32 +0300 Subject: [PATCH] fix(cmapi): MCOL-5962 Fix rollback in mcs cli and passing errors during broadcasting config * fix(cmapi): ClusterControllerClient request error handling * fix(cmapi): broadcast_new_config request error handling * style(cmapi): logs --- cmapi/cmapi_server/controllers/api_clients.py | 31 +++++++++++++++++-- cmapi/cmapi_server/controllers/endpoints.py | 2 +- cmapi/cmapi_server/helpers.py | 19 ++++++++---- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/cmapi/cmapi_server/controllers/api_clients.py b/cmapi/cmapi_server/controllers/api_clients.py index dd449258a..7b7e69622 100644 --- a/cmapi/cmapi_server/controllers/api_clients.py +++ b/cmapi/cmapi_server/controllers/api_clients.py @@ -1,12 +1,14 @@ -import requests +import logging from typing import Any, Dict, Optional, Union import pyotp +import requests from cmapi_server.controllers.dispatcher import _version from cmapi_server.constants import ( CMAPI_CONF_PATH, CURRENT_NODE_CMAPI_URL, SECRET_KEY, ) +from cmapi_server.exceptions import CMAPIBasicError from cmapi_server.helpers import get_config_parser, get_current_key @@ -146,5 +148,28 @@ class ClusterControllerClient: response.raise_for_status() return response.json() # TODO: different handler for timeout exception? - except requests.exceptions.RequestException as e: - return {'error': str(e)} + except requests.HTTPError as exc: + resp = exc.response + error_msg = str(exc) + if resp.status_code == 422: + # in this case we think cmapi server returned some value but + # had error during running endpoint handler code + try: + resp_json = response.json() + error_msg = resp_json.get('error', resp_json) + except requests.exceptions.JSONDecodeError: + error_msg = response.text + message = ( + f'API client got an exception in request to {exc.request.url} ' + f'with code {resp.status_code} and error: {error_msg}' + ) + logging.error(message) + raise CMAPIBasicError(message) + except requests.exceptions.RequestException as exc: + message = ( + 'API client got an undefined error in request to ' + f'{exc.request.url} with code {exc.response.status_code} and ' + f'error: {str(exc)}' + ) + logging.error(message) + raise CMAPIBasicError(message) diff --git a/cmapi/cmapi_server/controllers/endpoints.py b/cmapi/cmapi_server/controllers/endpoints.py index 27600d5b7..0c6a68b18 100644 --- a/cmapi/cmapi_server/controllers/endpoints.py +++ b/cmapi/cmapi_server/controllers/endpoints.py @@ -461,7 +461,7 @@ class ConfigController: module_logger, func_name, ( 'Error while starting node. ' - f'Details: {err.message}.' + f'Details: {err.message}' ), exc_info=False ) diff --git a/cmapi/cmapi_server/helpers.py b/cmapi/cmapi_server/helpers.py index b394a9bed..ee2ea914f 100644 --- a/cmapi/cmapi_server/helpers.py +++ b/cmapi/cmapi_server/helpers.py @@ -357,35 +357,42 @@ def broadcast_new_config( :raises CMAPIBasicError: If undefined error happened """ url = f'https://{node}:8640/cmapi/{version}/node/config' + resp_json: dict = dict() async with aiohttp.ClientSession() as session: try: async with session.put( url, headers=headers, json=body, ssl=False, timeout=120 ) as response: + resp_json = await response.json(encoding='utf-8') response.raise_for_status() - logging.info(f'Node "{node}" config put successfull.') + logging.info(f'Node {node} config put successfull.') except aiohttp.ClientResponseError as err: + # TODO: may be better to check if resp status is 422 cause + # it's like a signal that cmapi server raised it in + # most cases + error_msg = resp_json.get('error', resp_json) message = ( - f'Node "{node}" config put failed with status: ' - f'"{err.status}" and message: {err.message}' + f'Node {node} config put failed with status: ' + f'{err.status} and err message: {error_msg}' ) logging.error(message) raise CMAPIBasicError(message) except aiohttp.ClientError as err: + message = ( - f'Node "{node}" config put failed with ClientError: ' + f'Node {node} config put failed with ClientError: ' f'{str(err)}' ) logging.error(message) raise CMAPIBasicError(message) except asyncio.TimeoutError: - message = f'Node "{node}" config put failed by Timeout: ' + message = f'Node {node} config put failed by Timeout: ' logging.error(message) raise CMAPIBasicError(message) except Exception as err: message = ( - f'Node "{node}" config put failed by undefined exception: ' + f'Node {node} config put failed by undefined exception: ' f'{str(err)}' ) logging.error(message)