Skip to content

feat(sentry): add SentrySdkAspect for coroutine-safe SDK usage#1063

Merged
huangdijia merged 8 commits intomainfrom
feat/sentry-sdk-aspect
Mar 10, 2026
Merged

feat(sentry): add SentrySdkAspect for coroutine-safe SDK usage#1063
huangdijia merged 8 commits intomainfrom
feat/sentry-sdk-aspect

Conversation

@huangdijia
Copy link
Contributor

@huangdijia huangdijia commented Feb 27, 2026

Summary

  • Add SentrySdkAspect to make Sentry SDK methods coroutine-safe using Hyperf's Context API
  • Intercepts SentrySdk::init, ::setCurrentHub, and ::getRuntimeContextManager
  • Uses RuntimeContextManager stored in Hyperf's context for proper coroutine isolation

Test plan

  • Test Sentry integration in a coroutine environment
  • Verify that error tracing works correctly across multiple concurrent requests

Summary by CodeRabbit

  • 依赖更新

    • Sentry PHP 库已升级至 4.21.0(从 4.19.0)
  • 改进

    • 统一并简化了事件与度量的刷新路径,改为通过 Sentry SDK 的统一刷新接口
    • 协程与度量处理切换到基于 Sentry SDK 的集成,提升刷新一致性与稳定性

Add an aspect that intercepts SentrySdk::init, ::setCurrentHub, and
::getRuntimeContextManager to make them coroutine-safe using Hyperf's
Context API and RuntimeContextManager.

This ensures that Sentry SDK works correctly in a coroutine environment
by storing the runtime context manager in Hyperf's context storage.
Copilot AI review requested due to automatic review settings February 27, 2026 10:37
@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Walkthrough

sentry/sentry 依赖从 ^4.19.0 升级到 ^4.21.0;新增 AOP 切面 SentrySdkAspect 拦截 SentrySdk 的若干方法并在 Hyperf Context 中管理 RuntimeContextManager;删除 class_map 中的 SentrySdk 实现,并将多处 flush 调用替换为 SentrySdk::flush()

Changes

Cohort / File(s) Summary
依赖/包清单
composer.json, src/sentry/composer.json
sentry/sentry 版本从 ^4.19.0 升级到 ^4.21.0
新增切面
src/sentry/src/Aspect/SentrySdkAspect.php
新增 AOP 切面,拦截 SentrySdk::initSentrySdk::setCurrentHubSentrySdk::getRuntimeContextManager 并在 Hyperf Context 中创建/获取/更新 RuntimeContextManager。
移除 class_map 实现
src/sentry/class_map/SentrySdk.php
删除原有 class_map 中的 SentrySdk 静态实现,行为迁移至切面。
配置提供者
src/sentry/src/ConfigProvider.php
在配置中注册 SentrySdkAspect,并将 annotations 的 class_map 改为空数组(移除对本地 class_map 的映射)。
统一 flush 调用替换
src/sentry/src/.../Integration.php, src/sentry/src/Aspect/CoroutineAspect.php, src/sentry/src/Tracing/Aspect/CoroutineAspect.php, src/sentry/src/Tracing/Listener/EventHandleListener.php, src/sentry/src/Metrics/Listener/*.php, src/sentry/src/Metrics/Timer.php, src/sentry/src/Aspect/CoroutineAspect.php
将原来调用 Integration::flushEvents()(及部分注释的 metrics()->flush())替换为 SentrySdk::flush(),并相应更新 import,调用位置与触发时序保持不变。

Sequence Diagram(s)

sequenceDiagram
    participant App as 应用
    participant Aspect as SentrySdkAspect
    participant Context as Hyperf Context
    participant Manager as RuntimeContextManager
    participant Hub as HubInterface
    participant SDK as SentrySdk

    App->>Aspect: 调用 SentrySdk::init()
    Aspect->>Hub: 创建 Hub 实例
    Aspect->>Manager: 创建 RuntimeContextManager(Hub)
    Aspect->>Context: 存储 Manager
    Aspect->>App: 返回 Hub

    App->>Aspect: 调用 SentrySdk::setCurrentHub(hub)
    Aspect->>Context: 获取 Manager
    Aspect->>Manager: 设置当前 Hub
    Aspect->>App: 返回 hub

    App->>Aspect: 调用 SentrySdk::getRuntimeContextManager()
    Aspect->>Context: 查询 Manager
    alt 存在
        Aspect->>App: 返回 Manager
    else 不存在
        Aspect->>Hub: 创建 Hub
        Aspect->>Manager: 创建 Manager
        Aspect->>Context: 存储 Manager
        Aspect->>App: 返回 Manager
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • xuanyanwow
  • zds-s

Poem

🐰 我在代码林中跳一跳,依赖换新跑得俏;
切面织网守上下,Context 里安放小小 Hub;
Flush 一声轻轻叫,兔儿鼓掌庆修好。

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: adding SentrySdkAspect to enable coroutine-safe SDK usage, which is the central focus of this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/sentry-sdk-aspect

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PHPStan (2.1.40)

At least one path must be specified to analyse.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request attempts to add coroutine-safety to Sentry SDK usage by introducing a SentrySdkAspect that intercepts SentrySdk methods and uses Hyperf's Context API with RuntimeContextManager. However, this approach is fundamentally flawed because the codebase already implements coroutine-safety for SentrySdk through a class_map override (registered in ConfigProvider line 80, implemented in class_map/SentrySdk.php).

Changes:

  • Added SentrySdkAspect class to intercept SentrySdk methods
  • Registered the aspect in ConfigProvider
  • Attempted to use RuntimeContextManager for coroutine isolation

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.

File Description
src/sentry/src/ConfigProvider.php Registers the new SentrySdkAspect (conflicts with existing class_map)
src/sentry/src/Aspect/SentrySdkAspect.php New aspect attempting to make SentrySdk coroutine-safe (redundant and incompatible)

Comment on lines +55 to +56
$arguments = $proceedingJoinPoint->arguments ?? [];
$hub = $arguments['hub'];

This comment was marked as outdated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/sentry/src/Aspect/SentrySdkAspect.php (1)

43-43: 可选:移除未使用形参,消除静态分析噪音。

handleInit()handleGetRuntimeContextManager()$proceedingJoinPoint 未被使用,可删掉以减少 PHPMD 告警。

♻️ 建议修改
-            'init' => $this->handleInit($proceedingJoinPoint),
+            'init' => $this->handleInit(),
             'setCurrentHub' => $this->handleSetCurrentHub($proceedingJoinPoint),
-            'getRuntimeContextManager' => $this->handleGetRuntimeContextManager($proceedingJoinPoint),
+            'getRuntimeContextManager' => $this->handleGetRuntimeContextManager(),

-    private function handleInit(ProceedingJoinPoint $proceedingJoinPoint)
+    private function handleInit()
     {
         Context::set(
             RuntimeContextManager::class,
             new RuntimeContextManager(make(HubInterface::class))
         );

         return SentrySdk::getCurrentHub();
     }

-    private function handleGetRuntimeContextManager(ProceedingJoinPoint $proceedingJoinPoint)
+    private function handleGetRuntimeContextManager()
     {
         return Context::getOrSet(
             RuntimeContextManager::class,
             fn () => new RuntimeContextManager(make(HubInterface::class))
         );
     }

Also applies to: 63-63

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/sentry/src/Aspect/SentrySdkAspect.php` at line 43, Both handleInit() and
handleGetRuntimeContextManager() declare an unused ProceedingJoinPoint parameter
causing static-analysis noise; remove the unused parameter from both method
signatures (e.g., change "private function handleInit(ProceedingJoinPoint
$proceedingJoinPoint)" and "private function
handleGetRuntimeContextManager(ProceedingJoinPoint $proceedingJoinPoint)" to
signatures without parameters), ensure there are no internal references to
$proceedingJoinPoint, and update any callers or pointcut/advice mappings if they
reference the method signature so the aspect wiring remains correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/sentry/src/Aspect/SentrySdkAspect.php`:
- Line 43: Both handleInit() and handleGetRuntimeContextManager() declare an
unused ProceedingJoinPoint parameter causing static-analysis noise; remove the
unused parameter from both method signatures (e.g., change "private function
handleInit(ProceedingJoinPoint $proceedingJoinPoint)" and "private function
handleGetRuntimeContextManager(ProceedingJoinPoint $proceedingJoinPoint)" to
signatures without parameters), ensure there are no internal references to
$proceedingJoinPoint, and update any callers or pointcut/advice mappings if they
reference the method signature so the aspect wiring remains correct.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15d5ca9 and 8d0c644.

📒 Files selected for processing (4)
  • composer.json
  • src/sentry/composer.json
  • src/sentry/src/Aspect/SentrySdkAspect.php
  • src/sentry/src/ConfigProvider.php

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/sentry/src/Aspect/SentrySdkAspect.php`:
- Around line 54-55: The code is reading $arguments =
$proceedingJoinPoint->arguments['keys'] ?? []; and then accessing
$arguments['hub'] without checking existence which can throw an Undefined index
error; update the access to guard against missing 'hub' (e.g., retrieve with
$arguments['hub'] ?? null or use isset($arguments['hub']) before use) and add
handling when hub is null (early return, skip Sentry logic, or throw a clear
exception such as InvalidArgumentException) so the code using $arguments and
$proceedingJoinPoint does not assume the 'hub' key is present.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 81ff0dd8-c0f4-4a16-87d8-686bf7f879f9

📥 Commits

Reviewing files that changed from the base of the PR and between 8d0c644 and 042ed4e.

📒 Files selected for processing (14)
  • src/sentry/class_map/SentrySdk.php
  • src/sentry/src/Aspect/CoroutineAspect.php
  • src/sentry/src/Aspect/SentrySdkAspect.php
  • src/sentry/src/ConfigProvider.php
  • src/sentry/src/Integration.php
  • src/sentry/src/Metrics/Listener/OnBeforeHandle.php
  • src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php
  • src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php
  • src/sentry/src/Metrics/Listener/OnWorkerStart.php
  • src/sentry/src/Metrics/Listener/PoolWatcher.php
  • src/sentry/src/Metrics/Listener/QueueWatcher.php
  • src/sentry/src/Metrics/Timer.php
  • src/sentry/src/Tracing/Aspect/CoroutineAspect.php
  • src/sentry/src/Tracing/Listener/EventHandleListener.php
💤 Files with no reviewable changes (1)
  • src/sentry/class_map/SentrySdk.php

Comment on lines +54 to +55
$arguments = $proceedingJoinPoint->arguments['keys'] ?? [];
$hub = $arguments['hub'];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

参数访问缺少防御性检查,可能导致运行时错误。

$arguments 数组中不存在 hub 键时,第 55 行会抛出 Undefined index 错误。建议添加空值检查或更明确的错误处理。

🛡️ 建议的修复方案
     private function handleSetCurrentHub(ProceedingJoinPoint $proceedingJoinPoint)
     {
         $arguments = $proceedingJoinPoint->arguments['keys'] ?? [];
-        $hub = $arguments['hub'];
+        $hub = $arguments['hub'] ?? throw new \InvalidArgumentException('Hub argument is required');
         // `@phpstan-ignore-next-line`
         Closure::bind(fn () => static::getRuntimeContextManager()->setCurrentHub($hub), null, SentrySdk::class)();

         return $hub;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$arguments = $proceedingJoinPoint->arguments['keys'] ?? [];
$hub = $arguments['hub'];
private function handleSetCurrentHub(ProceedingJoinPoint $proceedingJoinPoint)
{
$arguments = $proceedingJoinPoint->arguments['keys'] ?? [];
$hub = $arguments['hub'] ?? throw new \InvalidArgumentException('Hub argument is required');
// `@phpstan-ignore-next-line`
Closure::bind(fn () => static::getRuntimeContextManager()->setCurrentHub($hub), null, SentrySdk::class)();
return $hub;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/sentry/src/Aspect/SentrySdkAspect.php` around lines 54 - 55, The code is
reading $arguments = $proceedingJoinPoint->arguments['keys'] ?? []; and then
accessing $arguments['hub'] without checking existence which can throw an
Undefined index error; update the access to guard against missing 'hub' (e.g.,
retrieve with $arguments['hub'] ?? null or use isset($arguments['hub']) before
use) and add handling when hub is null (early return, skip Sentry logic, or
throw a clear exception such as InvalidArgumentException) so the code using
$arguments and $proceedingJoinPoint does not assume the 'hub' key is present.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/sentry/src/Aspect/SentrySdkAspect.php`:
- Around line 55-63: handleSetCurrentHub currently uses Closure::bind to call
static::getRuntimeContextManager()->setCurrentHub($hub), which bypasses AOP and
returns the global cached RuntimeContextManager; replace that bypass with a
proper AOP-aware call: remove the Closure::bind call and instead let the
original join point execute (use $proceedingJoinPoint->proceed() or call
SentrySdk::getRuntimeContextManager() via the normal static call path so AOP can
intercept) and then call setCurrentHub on the resulting runtime context manager;
ensure you still return $hub and reference the existing symbols
handleSetCurrentHub, ProceedingJoinPoint::proceed,
SentrySdk::getRuntimeContextManager, and setCurrentHub.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2843a136-bc87-4891-96d4-375506fa99ec

📥 Commits

Reviewing files that changed from the base of the PR and between 042ed4e and 4ba375b.

📒 Files selected for processing (1)
  • src/sentry/src/Aspect/SentrySdkAspect.php

@huangdijia huangdijia merged commit e0a9602 into main Mar 10, 2026
23 checks passed
@huangdijia huangdijia deleted the feat/sentry-sdk-aspect branch March 10, 2026 01:54
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