Skip to content

fix: handle update position tpsl error handling, dedupe flipPosition trace#29817

Merged
gambinish merged 3 commits into
mainfrom
perps/tat-26559-handle-updatePositionTPSL-error-handling
May 13, 2026
Merged

fix: handle update position tpsl error handling, dedupe flipPosition trace#29817
gambinish merged 3 commits into
mainfrom
perps/tat-26559-handle-updatePositionTPSL-error-handling

Conversation

@gambinish

@gambinish gambinish commented May 6, 2026

Copy link
Copy Markdown
Member

Description

Fixes two Perps error-reporting gaps to make Sentry monitoring consistent across all trading write paths in TradingService:

  • updatePositionTPSL was silently missing controller-level logging. When a TP/SL update threw, the controller's catch block set traceData and rethrew but never called this.#deps.logger.error. Every other write method in TradingService (cancelOrder, cancelOrders, closePositions, updateMargin) calls logger.error in its catch. This gap is now closed.

  • flipPosition errors were double-reported to Sentry. The controller already calls this.#deps.logger.error (which routes to Sentry.captureException) when flipPosition throws. The UI hook usePerpsFlipPosition was catching the rethrown error and calling Logger.error again — sending the same event to Sentry twice. The redundant Logger.error call has been removed from the hook; the controller remains the single source of truth. User-facing feedback (error toast and onError callback) is preserved.

  • Fixed Perps trading errors (position close, order cancel) being silently swallowed when the provider reports failure — they now appear in Sentry with the underlying cause message

This will need to be synced with core to include changes to TradingService in order to propagate to extension

Changelog

CHANGELOG entry: Fixed missing controller-level Sentry reporting for TP/SL update failures in the Perps trading service
CHANGELOG entry: Fixed duplicate Sentry reports when a flipPosition call throws
Fixed missing Sentry logging when trading operations return a failure result without throwing: closePosition, cancelOrder, closePositions, and cancelOrders now call logger.error at the controller level

Related issues

Fixes:

Manual testing steps

Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]

Screenshots/Recordings

Before

After

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Touches Perps trading write paths to change when/where errors are logged and surfaced; low functional risk but could impact Sentry noise and observability if context or failure conditions are incorrect.

Overview
Improves Perps error reporting consistency by moving/adding controller-level logger.error calls when providers return failure results (not just when they throw), including single cancelOrder/closePosition failures and batch cancelOrders/closePositions partial/full failures.

Adds missing exception logging for updatePositionTPSL so thrown errors are captured with method/symbol context.

Removes Logger.error Sentry reporting from the UI usePerpsFlipPosition hook to avoid double-reporting exceptions (toast + onError behavior remains), and updates tests to assert the deduped behavior and the new controller logging.

Reviewed by Cursor Bugbot for commit 6230410. Bugbot is set up for automated code reviews on this repo. Configure here.

@metamaskbotv2 metamaskbotv2 Bot added the team-perps Perps team label May 6, 2026
@github-actions github-actions Bot added the size-M label May 6, 2026
@gambinish gambinish marked this pull request as ready for review May 6, 2026 19:37
@gambinish gambinish requested a review from a team as a code owner May 6, 2026 19:38
@gambinish gambinish added the DO-NOT-MERGE Pull requests that should not be merged label May 6, 2026
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePreps
  • Risk Level: low
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are confined to Perps-specific files:

  1. usePerpsFlipPosition.ts: Removed duplicate Logger.error call from the UI hook's error handler. Error reporting is now consolidated at the controller layer (TradingService). No functional logic changes — the hook still shows toasts and calls onError callbacks correctly.

  2. TradingService.ts: Added logger.error calls for non-throwing failure results in cancelOrder, cancelOrders (batch), closePosition, closePositions (batch), and updatePositionTPSL. These are purely observability improvements — no changes to return values, state management, or trading logic.

  3. Both test files update unit tests to reflect the new error reporting architecture.

Risk: Low — these are error logging/observability changes only. No functional behavior changes to trading operations, no UI rendering changes, no shared component modifications.

Tag selection rationale:

  • SmokePerps: Primary tag — changes directly affect Perps trading service (TradingService) and Perps UI hook (usePerpsFlipPosition). Need to verify the flip position, cancel order, close position, and TPSL flows still work correctly end-to-end.
  • SmokeWalletPlatform: Required per SmokePerps tag description — Perps is a section inside the Trending tab, so SmokeWalletPlatform must be included.
  • SmokeConfirmations: Required per SmokePerps tag description — Add Funds deposits and position management are on-chain transactions that go through confirmations.

No other tags are warranted as the changes are isolated to Perps functionality with no impact on accounts, identity, network, browser, snaps, swaps, or other features.

Performance Test Selection:
The changes touch TradingService.ts which is the core trading service for Perps. While the changes are purely error logging additions (no functional logic changes), running @PerformancePreps is a conservative choice to ensure the added logger.error calls in hot paths (cancelOrder, closePosition, etc.) don't introduce any measurable performance regression. However, since these are only error-path additions (not in the success/happy path), the actual performance impact is negligible. Selecting @PerformancePreps as a precaution given TradingService is a core Perps component.

View GitHub Actions results

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6230410. Configure here.

} catch (error) {
errorMessage = error instanceof Error ? error.message : 'Unknown error';
traceData = { success: false, error: errorMessage };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing logger.error for non-throwing TPSL provider failures

Medium Severity

The PR adds logger.error to the else branch (non-throwing provider failure) of cancelOrder and closePosition, but omits the same treatment for updatePositionTPSL. When the TPSL provider returns {success: false} without throwing, the else block at line 1783 sets traceData but never calls this.#deps.logger.error, so the failure is silently swallowed in Sentry. This contradicts the PR's stated goal of making Sentry monitoring consistent across all trading write paths.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6230410. Configure here.

@sonarqubecloud

sonarqubecloud Bot commented May 6, 2026

Copy link
Copy Markdown

@gambinish gambinish removed the DO-NOT-MERGE Pull requests that should not be merged label May 7, 2026
@gambinish gambinish enabled auto-merge May 12, 2026 19:41
@abretonc7s

Copy link
Copy Markdown
Contributor

Automated Review — PR #29817

BETA — Automated review from the farmslot pipeline.

Recommendation APPROVE
Runner claude / opus
Tier standard
Cost N/A (N/A tokens)
Recipe N/A

Summary

This PR closes three Sentry observability gaps in the Perps TradingService:

  1. Adds missing logger.error in updatePositionTPSL's catch block — previously set traceData and rethrew but never logged to Sentry.
  2. Removes duplicate Logger.error from usePerpsFlipPosition UI hook — the controller already reports to Sentry on flip failures; the hook was double-reporting.
  3. Adds logger.error for non-throwing failure paths ({success: false} results) in cancelOrder, closePosition, cancelOrders, and closePositions — these were silently swallowed.

All three claims are verified by code review and unit tests. The changes achieve their stated goal.

Full review details

Recipe Coverage

Skipped (standard-tier, skip-internal-logging-only). All claims concern internal Sentry/logger behavior with no UI surface.

# Claim (verbatim) Status Rationale
1 updatePositionTPSL missing logger.error UNTESTABLE Internal logging — verified via code review + unit test
2 flipPosition double-reported to Sentry UNTESTABLE Internal logging — verified via code review + unit test
3 closePosition/cancelOrder silently swallowed UNTESTABLE Internal logging — verified via code review + unit test

Overall recipe coverage: 0/3 ACs PROVEN (all verified via code review + tests)
Untestable: 1, 2, 3 — all claims are about internal logger.error behavior with no UI surface; unit tests are the correct proof

Prior Reviews

Reviewer State Date Addressed? Notes
cursor COMMENTED 2026-05-06 N/A Bugbot automated summary only

No human reviews yet.

Acceptance Criteria Validation

# Criterion Status Evidence
1 updatePositionTPSL logger.error added PASS Code review: TradingService.ts:1793-1800 adds logger.error in catch. Test: "logs error with message and context when provider throws" passes
2 flipPosition dedup PASS Code review: usePerpsFlipPosition.ts catch block no longer calls Logger.error. Test: "surfaces exception via toast and onError without double-reporting to Sentry" asserts Logger.error NOT called
3 Non-throwing failures now logged PASS Code review: cancelOrder:1126, closePosition:1454, cancelOrders:1323, closePositions:1659 all add logger.error. Tests assert logger.error called with correct Error + context

Code Quality

  • Pattern adherence: Follows codebase conventions. Uses ensureError for string→Error conversion, #getErrorContext for lightweight context.
  • Complexity: Appropriate — each change is a single logger.error call at the right place.
  • Type safety: No type issues introduced. ensureError correctly handles string | undefined error values.
  • Error handling: Adequate — errors are logged with method name, symbol, and provider error details.
  • Anti-pattern findings: None. No magic strings, no as any, no eslint-disable, no console.log.

Fix Quality

  • Best approach: Yes — this is the minimal, correct fix. Each added logger.error call follows the established pattern. The dedup in the UI hook is the right layer boundary: controller owns Sentry, UI owns toasts.
  • Would not ship: Nothing blocks merge.
  • Test quality: Strong. Tests assert the exact arguments passed to logger.error (Error message + context object). Negative tests verify batch logging does NOT fire on fallback paths. The usePerpsFlipPosition test asserts Logger.error is NOT called, which would fail if the removal is reverted.
  • Brittleness: Low. All logging uses stable internal APIs (#deps.logger.error, #getErrorContext, ensureError).

Live Validation

  • Recipe: skipped (standard-tier, internal-logging-only)
  • Result: SKIPPED — no UI surface to validate
  • Video: review.mp4 (brief app health capture)
  • Native changes: none
  • Metro errors: none PR-related (pre-existing Sentry type compat, appwright module, SnapUIRenderer resolution)
  • Log monitoring: Metro logs checked, no PR-related errors

Correctness

  • Diff vs stated goal: Aligned — all three stated changes are present and correct.
  • Edge cases:
    • ensureError(result.error) where result.error is undefined: produces "Unknown error (no details provided) [TradingService.*]" — acceptable.
    • Batch failure summary with many failures: string concatenation could produce very long error messages in Sentry. Not a correctness issue but worth monitoring.
  • Race conditions: None — all logging is synchronous within the existing try/catch flow.
  • Backward compatibility: Preserved. No public API changes. Additional Sentry events are additive.

Static Analysis

  • lint:tsc: PASS — no PR-related type errors (pre-existing errors in tests/appwright and Sentry type compat only)
  • Tests: 94/94 pass (2 suites)

Architecture & Domain

  • Error context format inconsistency: The new #getErrorContext calls produce {controller, method, ...} flat objects, while existing catch blocks use verbose {tags: {...}, context: {name, data: {...}}} format. This means the same method may send two different context shapes to Sentry depending on throw vs non-throwing failure. Pre-existing inconsistency, not introduced by this PR — suggestion to align in a follow-up.
  • File size: TradingService.ts at 2,119 lines (above 2,000 threshold). TradingService.test.ts at 2,413 lines. Both pre-existing but trending upward. This PR adds ~70 lines net. Consider splitting TradingService into per-operation modules in a follow-up.
  • JSDoc in usePerpsFlipPosition.ts line 19 still mentions "Sentry tracking" but the hook no longer does Sentry reporting. Stale comment.

Risk Assessment

  • [LOW] — Additive error logging only. No behavioral changes to success paths. Test coverage is comprehensive. The only risk is increased Sentry event volume from previously-silent failures, which is the intended effect.

Recommended Action

[APPROVE]

Minor suggestions:

  1. usePerpsFlipPosition.ts:19 — JSDoc still says "Sentry tracking" after removing Sentry reporting from this hook (nitpick)
  2. Consider aligning error context format between throw and non-throwing failure paths in a follow-up (suggestion)
  3. TradingService.ts at 2,119 lines — monitor file size growth (suggestion)
Line comments (3 comments: 2 suggestion, 1 nitpick)
  • [nitpick] app/components/UI/Perps/hooks/usePerpsFlipPosition.ts:19: JSDoc still mentions "Sentry tracking" but this hook no longer reports to Sentry (that's now the controller's responsibility). Consider updating to reflect the current behavior, e.g. "Provides consistent error handling and toast notifications".
  • [suggestion] app/controllers/perps/services/TradingService.ts:1126: The new #getErrorContext calls produce a flat {controller, method, ...} object, while the existing catch block at line 1491 uses the verbose {tags: {...}, context: {name, data: {...}}} format. This means Sentry events for the same method will have different context shapes depending on throw vs non-throwing failure. Consider aligning both paths in a follow-up so Sentry dashboards can query consistently.
  • [suggestion] app/controllers/perps/services/TradingService.ts:2119: TradingService.ts is at 2,119 lines (above the 2,000-line threshold). This PR adds ~70 lines of necessary logging. Consider splitting into per-operation modules (e.g. OrderService, PositionService, TPSLService) in a follow-up to keep each file manageable.

review.mp4 (88K)

@abretonc7s abretonc7s left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review — see comment above for full details.

@gambinish gambinish added this pull request to the merge queue May 13, 2026
},
);

this.#deps.logger.error(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion — The new #getErrorContext calls produce a flat {controller, method, ...} object, while the existing catch block at line 1491 uses the verbose {tags: {...}, context: {name, data: {...}}} format. This means Sentry events for the same method will have different context shapes depending on throw vs non-throwing failure. Consider aligning both paths in a follow-up so Sentry dashboards can query consistently.

Merged via the queue into main with commit 3650d1b May 13, 2026
180 of 183 checks passed
@gambinish gambinish deleted the perps/tat-26559-handle-updatePositionTPSL-error-handling branch May 13, 2026 15:58
@github-actions github-actions Bot locked and limited conversation to collaborators May 13, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.78.0 Issue or pull request that will be included in release 7.78.0 label May 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.78.0 Issue or pull request that will be included in release 7.78.0 size-M team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants