Skip to content

Fix #1845: fix: 修一下util里的timer_with_status的问题#1846

Open
Memtensor-AI wants to merge 1 commit into
dev-20260604-v2.0.19from
autodev/MemOS-1845
Open

Fix #1845: fix: 修一下util里的timer_with_status的问题#1846
Memtensor-AI wants to merge 1 commit into
dev-20260604-v2.0.19from
autodev/MemOS-1845

Conversation

@Memtensor-AI
Copy link
Copy Markdown
Collaborator

Description

修复 src/memos/utils.py::timed_with_status 的静默吞异常 bug。原行为:当未传 fallback 时,被装饰函数抛出的异常会被 except 捕获后丢失,包装器返回 None——这正是 format_utils.py:1410-1415 里那条"clean_json_response received None — upstream LLM call likely failed silently"防御注释指控的源头。新行为:未传 fallback 时,先在 finally 内照常打 [TIMER_WITH_STATUS] ... status: FAILED 日志,再把原异常重新抛出,traceback / __cause__ / __context__ 保持不变;传了 fallback 时路径完全不变。顺手给 timed 装饰器补了 functools.wraps,停止把 __name__ / __doc__ 弄丢。

生产侧受影响的两个调用点 OpenAILLM.generate / generate_stream 函数体内本来就有 raise,装饰器现在终于把这个意图传到上层;另外三个用了 fallback 的调用点 (UniversalAPIEmbedder.get_embeddingsHttpBGEReranker.rerank) 行为零变化。

测试改动:把原 test_failure_logging_no_fallback(之前以"应静默"为契约)改成断言异常需向上传播且 FAILED 日志仍要打;新增 test_failure_no_fallback_preserves_original_exception(同对象身份 + 无合成链)和 test_preserves_function_metadata (@timed 元数据)。沙箱内无法跑 make test(缺 transformers 等大依赖),用最小化 memos 命名空间桩跑 pytest tests/test_utils_timing.py33 passed;并把修复回滚为旧实现重跑两条新用例,两条均按预期 DID NOT RAISE 红——TDD 证据完整。ruff check / ruff format --check 在改动文件上均通过;本地分支已 push 到 origin/autodev/MemOS-1845。specs 仓库归档了 00-decision.md / 01-clarification.md / 03-fix.md / 04-integration-report.md

Related Issue (Required): Fixes #1845

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update

How Has This Been Tested?

Executor did not report tests.

  • Unit Test
  • Test Script Or Test Steps (please provide)
  • Pipeline Automated API Test (please provide)

Checklist

  • I have performed a self-review of my own code | 我已自行检查了自己的代码
  • I have commented my code in hard-to-understand areas | 我已在难以理解的地方对代码进行了注释
  • I have added tests that prove my fix is effective or that my feature works | 我已添加测试以证明我的修复有效或功能正常
  • I have created related documentation issue/PR in MemOS-Docs (if applicable) | 我已在 MemOS-Docs 中创建了相关的文档 issue/PR(如果适用)
  • I have linked the issue to this PR (if applicable) | 我已将 issue 链接到此 PR(如果适用)
  • I have mentioned the person who will review this PR | 我已提及将审查此 PR 的人

@CarltonXiang, @syzsunshine219 please review this PR.

Reviewer Checklist

📋 opsp 产物

本任务的设计文档、澄清记录、集成报告归档在 specs 仓库:
https://github.com/MemTensor/memos-autodev-specs/tree/main/2026-06-01-1845-fix-修一下util里的timerwithstatus的问题/

(异步推送,短时间内访问可能 404,稍候再试。)

`timed_with_status` previously swallowed exceptions silently when no
`fallback` was supplied, returning `None` to the caller. This is the
exact footgun the inline note in
`src/memos/mem_os/utils/format_utils.py:1410-1415` calls out:
`clean_json_response received None — upstream LLM call likely failed
silently (check timed_with_status / generate() error handling)`.

Behaviour after the fix:

- `fallback` supplied → unchanged: fallback's return value is returned,
  status is logged as FAILED.
- `fallback` is `None` → original exception is re-raised after the
  `finally` block has emitted the `[TIMER_WITH_STATUS] ... status:
  FAILED` log line. Exception identity and chain
  (`__cause__` / `__context__`) are preserved.

Affected production call-sites: `OpenAILLM.generate` and
`OpenAILLM.generate_stream` (which already `raise` inside the function
body — the decorator now honours that intent). The three call-sites
that supply a fallback (`UniversalAPIEmbedder.get_embeddings`,
`HttpBGEReranker.rerank`) are unaffected.

Also added `@functools.wraps(fn)` to the plain `timed` decorator so it
stops clobbering `__name__` / `__doc__`.

Tests:

- `test_failure_logging_no_fallback` updated to assert the exception
  propagates while the FAILED log is still emitted.
- `test_failure_no_fallback_preserves_original_exception` (new): asserts
  same-object identity + no synthetic chaining.
- `test_preserves_function_metadata` (new) for `@timed`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants