mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-09-14 23:21:04 +00:00
fix(job): preserve nested exception details (#544)
This commit is contained in:
parent
4f7c8786e3
commit
46eca95bb9
2 changed files with 40 additions and 1 deletions
|
|
@ -13,6 +13,25 @@ if TYPE_CHECKING:
|
|||
from ...steps import BaseStep
|
||||
|
||||
|
||||
def _describe_exception(exc: BaseException) -> str:
|
||||
"""Render an exception and its causes without dropping empty messages."""
|
||||
parts: list[str] = []
|
||||
current: BaseException | None = exc
|
||||
seen: set[int] = set()
|
||||
while current is not None and id(current) not in seen:
|
||||
seen.add(id(current))
|
||||
message = str(current).strip()
|
||||
name = type(current).__name__
|
||||
parts.append(f"{name}: {message}" if message else name)
|
||||
if current.__cause__ is not None:
|
||||
current = current.__cause__
|
||||
elif not current.__suppress_context__:
|
||||
current = current.__context__
|
||||
else:
|
||||
current = None
|
||||
return " <- ".join(parts)
|
||||
|
||||
|
||||
@R.register("base")
|
||||
class BaseJob(BaseComponent):
|
||||
"""Job that executes steps sequentially and returns a Response."""
|
||||
|
|
@ -75,5 +94,5 @@ class BaseJob(BaseComponent):
|
|||
except Exception as e:
|
||||
self.logger.exception(f"Failed to execute job: {e}")
|
||||
context.response.success = False
|
||||
context.response.answer = str(e)
|
||||
context.response.answer = _describe_exception(e)
|
||||
return context.response
|
||||
|
|
|
|||
|
|
@ -71,6 +71,26 @@ def test_call_captures_exception():
|
|||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_call_preserves_cause_when_outer_exception_message_is_empty():
|
||||
async def run():
|
||||
async def failing_step(_context):
|
||||
try:
|
||||
raise RuntimeError("connection reset by peer")
|
||||
except RuntimeError as exc:
|
||||
raise ConnectionError() from exc
|
||||
|
||||
job = BaseJob(name="j")
|
||||
job.app_context = MagicMock()
|
||||
job.step_specs = []
|
||||
job._build_steps = lambda: [failing_step]
|
||||
|
||||
response = await job()
|
||||
assert response.success is False
|
||||
assert response.answer == ("ConnectionError <- RuntimeError: connection reset by peer")
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def test_call_runs_steps_in_order():
|
||||
async def run():
|
||||
call_order = []
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue