Commit 66fb9456 authored by Natalia Grigoriadou's avatar Natalia Grigoriadou
Browse files

added a ToolError to display the OEG error message

parent 6004f606
Loading
Loading
Loading
Loading
Loading
+12 −11
Changes for mcp_module/tools/edge_application.py: 12 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ from mcp_module.models.edge_application_models import (
    RegisterAppDefinitionInput,
)
from mcp_module.security.authorization import get_oeg_authorization_headers
from mcp_module.tools.oeg_errors import raise_for_oeg_status

# Configure logging
logging.basicConfig(
@@ -70,7 +71,7 @@ async def get_app_definitions(
            response = await client.get(
                url, headers=headers, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to fetch edge application definitions: %s", e)
        raise
@@ -138,7 +139,7 @@ async def register_app_definition(
            response = await client.post(
                url, headers=headers, json=payload, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to register app definition: %s", e)
        raise
@@ -169,7 +170,7 @@ async def delete_app_definition(
            response = await client.delete(
                url, headers=headers, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to delete app definition %s: %s", inp.appId, e)
        raise
@@ -203,7 +204,7 @@ async def get_app_definition(
            response = await client.get(
                url, headers=headers, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to fetch app definition %s: %s", inp.appId, e)
        raise
@@ -250,7 +251,7 @@ async def get_edge_cloud_zones(
                follow_redirects=True,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to fetch edge cloud zones: %s", e)
        raise
@@ -303,7 +304,7 @@ async def instantiate_app(
            response = await client.post(
                url, headers=headers, json=payload, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to instantiate app %s: %s", inp.appId, e)
        raise
@@ -343,7 +344,7 @@ async def get_app_instances(
            response = await client.get(
                url, headers=headers, params=params, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to fetch app instances: %s", e)
        raise
@@ -374,7 +375,7 @@ async def delete_app_instance(
            response = await client.delete(
                url, headers=headers, follow_redirects=True, timeout=15
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to delete app instance %s: %s", inp.appInstanceId, e)
        raise
@@ -437,7 +438,7 @@ async def create_app_deployment(
                follow_redirects=True,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to create application deployment: %s", e)
        raise
@@ -490,7 +491,7 @@ async def get_app_deployments(
                follow_redirects=True,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to fetch application deployments: %s", e)
        raise
@@ -528,7 +529,7 @@ async def delete_app_deployment(
                follow_redirects=True,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error(
            "Failed to delete application deployment %s: %s",
+2 −1
Changes for mcp_module/tools/location.py: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ from dotenv import load_dotenv

from mcp_module.models.location_models import RetrieveLocationInput
from mcp_module.security.authorization import get_oeg_authorization_headers
from mcp_module.tools.oeg_errors import raise_for_oeg_status

logger = logging.getLogger("MCP server")

@@ -66,7 +67,7 @@ async def retrieve_location(
                json=payload,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to retrieve device location: %s", e)
        raise
+29 −0
Changes for mcp_module/tools/oeg_errors.py: 29 added lines, 0 removed lines.
Original line number Diff line number Diff line
"""Expose OEG's CAMARA errors to the model without leaking raw HTTP bodies."""

import httpx
from fastmcp.exceptions import ToolError


def raise_for_oeg_status(response: httpx.Response) -> None:
    """Keep successful responses intact; report failed calls as MCP tool errors."""
    if 200 <= response.status_code < 300:
        return

    code = None
    message = None
    try:
        body = response.json()
    except ValueError:
        body = None
    if isinstance(body, dict):
        code = body.get("code")
        message = body.get("message")

    details = [f"OEG HTTP {response.status_code}"]
    if isinstance(code, str) and code.strip():
        details.append(code)
    if isinstance(message, str) and message.strip():
        details.append(message)
    else:
        details.append(response.reason_phrase or "Request failed")
    raise ToolError(": ".join(details))
+4 −3
Changes for mcp_module/tools/qod.py: 4 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ logging.basicConfig(
    level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s"
)
from mcp_module.security.authorization import get_oeg_authorization_headers
from mcp_module.tools.oeg_errors import raise_for_oeg_status

logger = logging.getLogger("MCP server")

@@ -73,7 +74,7 @@ async def create_qod_session_oai(
                json=payload,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to create QoD session: %s", e)
        raise
@@ -99,7 +100,7 @@ async def get_qod_session_oai(
    try:
        async with httpx.AsyncClient(trust_env=True) as client:
            response = await client.get(session_url, headers=headers, timeout=15)
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to get session %s: %s", inp.sessionId, e)
        raise
@@ -133,7 +134,7 @@ async def delete_qod_session_oai(
                headers=headers,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to delete session %s: %s", inp.sessionId, e)
        raise
+5 −4
Changes for mcp_module/tools/traffic_influence.py: 5 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ from mcp_module.models.traffic_influence_models import (
    CreateTrafficInfluenceInput,
)
from mcp_module.security.authorization import get_oeg_authorization_headers
from mcp_module.tools.oeg_errors import raise_for_oeg_status

logger = logging.getLogger("MCP server")

@@ -74,7 +75,7 @@ async def create_traffic_influence(
                json=payload,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to create traffic influence: %s", e)
        raise
@@ -117,7 +118,7 @@ async def get_traffic_influences(
                params=params,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error("Failed to fetch traffic influences: %s", e)
        raise
@@ -156,7 +157,7 @@ async def get_traffic_influence(
                headers=headers,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error(
            "Failed to fetch traffic influence %s: %s",
@@ -199,7 +200,7 @@ async def delete_traffic_influence(
                headers=headers,
                timeout=15,
            )
            response.raise_for_status()
            raise_for_oeg_status(response)
    except httpx.HTTPError as e:
        logger.error(
            "Failed to delete traffic influence %s: %s",
Loading