Skip to content

Commit c71d333

Browse files
authored
fix: improve error handling in InvokeHandler and return detailed error responses (#53)
2 parents c56bd97 + c263fbf commit c71d333

1 file changed

Lines changed: 67 additions & 4 deletions

File tree

agentkit/apps/simple_app/simple_app_handlers.py

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import asyncio
16+
import json
1617
import inspect
1718
import logging
1819
import threading
@@ -22,6 +23,7 @@
2223
from typing import Any, Callable, Optional
2324
from typing_extensions import override
2425

26+
from starlette.exceptions import HTTPException
2527
from starlette.requests import Request
2628
from starlette.responses import JSONResponse, Response, StreamingResponse
2729

@@ -33,6 +35,13 @@
3335
logger = logging.getLogger("agentkit." + __name__)
3436

3537

38+
class InvalidJSONPayloadError(Exception): ...
39+
40+
41+
def _build_error_content(message: str, error_type: str) -> dict[str, dict[str, str]]:
42+
return {"error": {"message": message, "type": error_type}}
43+
44+
3645
class BaseHandler(ABC):
3746
def __init__(self, func: Callable | None = None) -> None:
3847
self.func = func
@@ -46,7 +55,13 @@ class InvokeHandler(BaseHandler):
4655
async def handle(self, request: Request) -> Response | StreamingResponse:
4756
if not self.func:
4857
logger.error("Invoke handler function is not set")
49-
return Response(status_code=404)
58+
return JSONResponse(
59+
status_code=404,
60+
content=_build_error_content(
61+
message="Entrypoint function is not set. Please register a function with @app.entrypoint.",
62+
error_type="NotFound",
63+
),
64+
)
5065

5166
span = telemetry.tracer.start_span(name="agentkit_invocation")
5267
ctx = trace.set_span_in_context(span)
@@ -72,13 +87,58 @@ async def handle(self, request: Request) -> Response | StreamingResponse:
7287
media_type="text/event-stream",
7388
)
7489

90+
if isinstance(result, Response):
91+
logger.info("Returning Starlette response")
92+
telemetry.trace_agent_finish("", None)
93+
return result
94+
7595
logger.info("Returning non-streaming response")
7696
safe_json_string = safe_serialize_to_json_string(result)
7797
telemetry.trace_agent_finish(safe_json_string, None)
98+
except InvalidJSONPayloadError as e:
99+
logger.warning("Failed to parse JSON payload: %s", e)
100+
telemetry.trace_agent_finish("", e)
101+
return JSONResponse(
102+
status_code=400,
103+
content=_build_error_content(
104+
message="Invalid JSON payload. Please provide a valid JSON object in the request body.",
105+
error_type="BadRequest",
106+
),
107+
)
108+
except HTTPException as e:
109+
logger.info("Returning HTTP exception: %s", e.status_code)
110+
status_code = int(getattr(e, "status_code", 500) or 500)
111+
detail = getattr(e, "detail", "")
112+
if status_code < 500:
113+
telemetry.trace_agent_finish("", None)
114+
if isinstance(detail, str):
115+
message = detail
116+
else:
117+
message = safe_serialize_to_json_string(detail)
118+
content = _build_error_content(
119+
message=message, error_type="HTTPException"
120+
)
121+
else:
122+
telemetry.trace_agent_finish("", e)
123+
content = _build_error_content(
124+
message="An error occurred inside the user-defined entrypoint function (decorated with @app.entrypoint). This is likely caused by the agent application, not AgentKit. Please contact agent administrator and check the Runtime logs.",
125+
error_type="HTTPException",
126+
)
127+
return JSONResponse(
128+
status_code=status_code,
129+
content=content,
130+
headers=getattr(e, "headers", None),
131+
)
78132
except Exception as e:
79-
logger.error("Invoke handler function failed: %s", e)
133+
logger.exception("Invoke handler function failed: %s", e)
80134
telemetry.trace_agent_finish("", e)
81-
raise e
135+
return JSONResponse(
136+
status_code=500,
137+
content=_build_error_content(
138+
message="An error occurred inside the user-defined entrypoint function (decorated with @app.entrypoint). This is likely caused by the agent application, not AgentKit. Please contact agent administrator and check the Runtime logs.",
139+
error_type=type(e).__name__,
140+
),
141+
)
82142

83143
return Response(safe_json_string, media_type="application/json")
84144

@@ -99,7 +159,10 @@ async def _process_invoke(self, request: Request) -> tuple[dict, dict, Any]:
99159
return {}, {}, {"message": "Invoke handler function is not set."}
100160

101161
# parse request
102-
payload: dict = await request.json()
162+
try:
163+
payload: dict = await request.json()
164+
except json.JSONDecodeError as e:
165+
raise InvalidJSONPayloadError(str(e)) from e
103166
headers: dict = dict(request.headers)
104167

105168
# parse entrypoint function params

0 commit comments

Comments
 (0)