@metamask-previews/perps-controller 20.0.0-preview-44b7ded21 → 20.0.0-preview-2750df1dc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"TradingService.d.ts","sourceRoot":"","sources":["../../src/services/TradingService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TradingService.d.ts","sourceRoot":"","sources":["../../src/services/TradingService.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ import { PerpsMeasurementName } from '../constants/performanceMetrics.js';
6
6
  import { PERPS_CONSTANTS } from '../constants/perpsConfig.js';
7
7
  import { PERPS_ERROR_CODES } from '../perpsErrorCodes.js';
8
8
  import { PerpsAnalyticsEvent, PerpsTraceNames, PerpsTraceOperations, } from '../types/index.js';
9
+ import { PERPS_ERROR_ACTION, PERPS_ERROR_OPERATION, createPerpsErrorContext, wasProviderErrorReported, } from '../utils/errorContext.js';
9
10
  import { ensureError } from '../utils/errorUtils.js';
10
11
  import { captureScaleOrderParams } from '../utils/lighterScaleOrders.js';
11
12
  import { isLimitExecutionOrderType, SCALE_ORDER_COUNT, } from '../utils/orderTypes.js';
@@ -20,6 +21,28 @@ import { isLimitExecutionOrderType, SCALE_ORDER_COUNT, } from '../utils/orderTyp
20
21
  function isSignerUnavailable(error) {
21
22
  return error === PERPS_ERROR_CODES.KEYRING_LOCKED;
22
23
  }
24
+ /**
25
+ * Flip results that are expected account or signer states, not defects.
26
+ * A locked keyring is retried by the user. A missing exchange account is the
27
+ * pre-account state already kept out of error reporting by the provider.
28
+ *
29
+ * @param error - The provider result error.
30
+ * @returns True for `KEYRING_LOCKED` and `EXCHANGE_ACCOUNT_NOT_FOUND`.
31
+ */
32
+ function isSilentFlipResult(error) {
33
+ return (isSignerUnavailable(error) ||
34
+ error === PERPS_ERROR_CODES.EXCHANGE_ACCOUNT_NOT_FOUND);
35
+ }
36
+ /**
37
+ * Convert an operation result into the bounded terminal trace status that
38
+ * platform adapters map to their tracing SDK.
39
+ *
40
+ * @param success - Whether the traced operation completed successfully.
41
+ * @returns The terminal trace status.
42
+ */
43
+ function getTraceStatus(success) {
44
+ return success === true ? 'ok' : 'error';
45
+ }
23
46
  /**
24
47
  * TradingService
25
48
  *
@@ -62,16 +85,21 @@ export class TradingService {
62
85
  /**
63
86
  * Error context helper for consistent logging
64
87
  *
88
+ * @param context - The active service context.
65
89
  * @param method - The method name.
90
+ * @param errorTags - Bounded tags used by error dashboards.
66
91
  * @param additionalContext - The additional context value.
67
92
  * @returns The resulting string value.
68
93
  */
69
- #getErrorContext(method, additionalContext) {
70
- return {
71
- controller: 'TradingService',
94
+ #getErrorContext(context, method, errorTags, additionalContext) {
95
+ return createPerpsErrorContext({
96
+ contextName: 'TradingService',
72
97
  method,
73
- ...additionalContext,
74
- };
98
+ provider: context.tracingContext.provider,
99
+ network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
100
+ errorTags,
101
+ data: additionalContext,
102
+ });
75
103
  }
76
104
  /**
77
105
  * Build discovery/attribution properties shared across trade/close/cancel/risk
@@ -344,21 +372,13 @@ export class TradingService {
344
372
  ? parseFloat(params.takeProfitPrice)
345
373
  : undefined,
346
374
  }).catch((error) => {
347
- this.#deps.logger.error(ensureError(error, 'TradingService.handleOrderSuccess'), {
348
- tags: {
349
- feature: PERPS_CONSTANTS.FeatureName,
350
- provider: context.tracingContext.provider,
351
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
352
- },
353
- context: {
354
- name: context.errorContext.controller,
355
- data: {
356
- method: context.errorContext.method,
357
- operation: 'reportOrderToDataLake',
358
- symbol: params.symbol,
359
- },
360
- },
361
- });
375
+ this.#deps.logger.error(ensureError(error, 'TradingService.handleOrderSuccess'), this.#getErrorContext(context, context.errorContext.method, {
376
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
377
+ action: PERPS_ERROR_ACTION.PlaceOrder,
378
+ }, {
379
+ operation: 'reportOrderToDataLake',
380
+ symbol: params.symbol,
381
+ }));
362
382
  });
363
383
  }
364
384
  /**
@@ -448,7 +468,7 @@ export class TradingService {
448
468
  message: 'Order execution started',
449
469
  level: 'info',
450
470
  data: {
451
- payment_token: paymentToken,
471
+ pay_token_symbol: paymentToken,
452
472
  market: params.symbol,
453
473
  orderType: params.orderType,
454
474
  },
@@ -464,12 +484,12 @@ export class TradingService {
464
484
  market: params.symbol,
465
485
  leverage: String(params.leverage ?? 1),
466
486
  isTestnet: String(context.tracingContext.isTestnet),
467
- payment_token: paymentToken,
487
+ pay_token_symbol: paymentToken,
468
488
  },
469
489
  data: {
470
490
  isBuy: params.isBuy,
471
491
  orderPrice: params.price ?? '',
472
- payment_token: paymentToken,
492
+ pay_token_symbol: paymentToken,
473
493
  },
474
494
  });
475
495
  // Calculate fee discount at execution time (fresh, secure)
@@ -514,7 +534,7 @@ export class TradingService {
514
534
  level: 'warning',
515
535
  data: {
516
536
  thresholdMs: PERPS_CONSTANTS.PlaceOrderTimeoutMs,
517
- payment_token: paymentToken,
537
+ pay_token_symbol: paymentToken,
518
538
  market: params.symbol,
519
539
  orderType: params.orderType,
520
540
  },
@@ -587,21 +607,13 @@ export class TradingService {
587
607
  duration: completionDuration,
588
608
  });
589
609
  // withFeeDiscount handles fee discount cleanup automatically
590
- this.#deps.logger.error(ensureError(error, 'TradingService.placeOrder'), {
591
- tags: {
592
- feature: PERPS_CONSTANTS.FeatureName,
593
- provider: context.tracingContext.provider,
594
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
595
- },
596
- context: {
597
- name: context.errorContext.controller,
598
- data: {
599
- method: context.errorContext.method,
600
- symbol: params.symbol,
601
- orderType: params.orderType,
602
- },
603
- },
604
- });
610
+ this.#deps.logger.error(ensureError(error, 'TradingService.placeOrder'), this.#getErrorContext(context, context.errorContext.method, {
611
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
612
+ action: PERPS_ERROR_ACTION.PlaceOrder,
613
+ }, {
614
+ symbol: params.symbol,
615
+ orderType: params.orderType,
616
+ }));
605
617
  traceData = {
606
618
  success: false,
607
619
  reason: didExceedOrderSubmissionThreshold ? 'late_error' : 'error',
@@ -617,6 +629,7 @@ export class TradingService {
617
629
  this.#deps.tracer.endTrace({
618
630
  name: PerpsTraceNames.PlaceOrder,
619
631
  id: traceId,
632
+ status: getTraceStatus(traceData?.success),
620
633
  data: traceData,
621
634
  });
622
635
  }
@@ -893,21 +906,13 @@ export class TradingService {
893
906
  action: 'close',
894
907
  symbol,
895
908
  }).catch((error) => {
896
- this.#deps.logger.error(ensureError(error, 'TradingService.handleDataLakeReporting'), {
897
- tags: {
898
- feature: PERPS_CONSTANTS.FeatureName,
899
- provider: context.tracingContext.provider,
900
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
901
- },
902
- context: {
903
- name: context.errorContext.controller,
904
- data: {
905
- method: context.errorContext.method,
906
- operation: 'reportOrderToDataLake',
907
- symbol,
908
- },
909
- },
910
- });
909
+ this.#deps.logger.error(ensureError(error, 'TradingService.handleDataLakeReporting'), this.#getErrorContext(context, context.errorContext.method, {
910
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
911
+ action: PERPS_ERROR_ACTION.ClosePosition,
912
+ }, {
913
+ operation: 'reportOrderToDataLake',
914
+ symbol,
915
+ }));
911
916
  });
912
917
  }
913
918
  /**
@@ -1246,20 +1251,12 @@ export class TradingService {
1246
1251
  [PERPS_EVENT_PROPERTY.COMPLETION_DURATION]: completionDuration,
1247
1252
  [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: error instanceof Error ? error.message : 'Unknown error',
1248
1253
  });
1249
- this.#deps.logger.error(ensureError(error, 'TradingService.editOrder'), {
1250
- tags: {
1251
- feature: PERPS_CONSTANTS.FeatureName,
1252
- provider: context.tracingContext.provider,
1253
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
1254
- },
1255
- context: {
1256
- name: context.errorContext.controller,
1257
- data: {
1258
- method: context.errorContext.method,
1259
- orderId: params.orderId,
1260
- },
1261
- },
1262
- });
1254
+ this.#deps.logger.error(ensureError(error, 'TradingService.editOrder'), this.#getErrorContext(context, context.errorContext.method, {
1255
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
1256
+ action: PERPS_ERROR_ACTION.EditOrder,
1257
+ }, {
1258
+ orderId: params.orderId,
1259
+ }));
1263
1260
  traceData = {
1264
1261
  success: false,
1265
1262
  error: error instanceof Error ? error.message : 'Unknown error',
@@ -1270,6 +1267,7 @@ export class TradingService {
1270
1267
  this.#deps.tracer.endTrace({
1271
1268
  name: PerpsTraceNames.EditOrder,
1272
1269
  id: traceId,
1270
+ status: getTraceStatus(traceData?.success),
1273
1271
  data: traceData,
1274
1272
  });
1275
1273
  }
@@ -1346,7 +1344,10 @@ export class TradingService {
1346
1344
  ...cancelExtraProps,
1347
1345
  });
1348
1346
  if (!isSignerUnavailable(result.error)) {
1349
- this.#deps.logger.error(ensureError(result.error, 'TradingService.cancelOrder'), this.#getErrorContext('cancelOrder', {
1347
+ this.#deps.logger.error(ensureError(result.error, 'TradingService.cancelOrder'), this.#getErrorContext(context, 'cancelOrder', {
1348
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
1349
+ action: PERPS_ERROR_ACTION.CancelOrder,
1350
+ }, {
1350
1351
  symbol: params.symbol,
1351
1352
  orderId: params.orderId,
1352
1353
  providerError: result.error ?? 'Unknown error',
@@ -1366,7 +1367,10 @@ export class TradingService {
1366
1367
  [PERPS_EVENT_PROPERTY.ERROR_MESSAGE]: error instanceof Error ? error.message : 'Unknown error',
1367
1368
  ...cancelExtraProps,
1368
1369
  });
1369
- this.#deps.logger.error(ensureError(error, 'TradingService.cancelOrder'), this.#getErrorContext('cancelOrder', { symbol: params.symbol }));
1370
+ this.#deps.logger.error(ensureError(error, 'TradingService.cancelOrder'), this.#getErrorContext(context, 'cancelOrder', {
1371
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
1372
+ action: PERPS_ERROR_ACTION.CancelOrder,
1373
+ }, { symbol: params.symbol }));
1370
1374
  traceData = {
1371
1375
  success: false,
1372
1376
  error: error instanceof Error ? error.message : 'Unknown error',
@@ -1377,6 +1381,7 @@ export class TradingService {
1377
1381
  this.#deps.tracer.endTrace({
1378
1382
  name: PerpsTraceNames.CancelOrder,
1379
1383
  id: traceId,
1384
+ status: getTraceStatus(traceData?.success),
1380
1385
  data: traceData,
1381
1386
  });
1382
1387
  }
@@ -1494,7 +1499,10 @@ export class TradingService {
1494
1499
  const failureSummary = reportedFailures
1495
1500
  .map((result) => `${result.symbol}/${result.orderId}: ${result.error ?? 'Unknown error'}`)
1496
1501
  .join('; ');
1497
- this.#deps.logger.error(new Error(`cancelOrders batch failure: ${operationResult.failureCount}/${operationResult.results.length} failed (${reportedFailures.length} reported) - ${failureSummary}`), this.#getErrorContext('cancelOrders', {
1502
+ this.#deps.logger.error(new Error(`cancelOrders batch failure: ${operationResult.failureCount}/${operationResult.results.length} failed (${reportedFailures.length} reported) - ${failureSummary}`), this.#getErrorContext(context, 'cancelOrders', {
1503
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
1504
+ action: PERPS_ERROR_ACTION.CancelOrder,
1505
+ }, {
1498
1506
  successCount: operationResult.successCount,
1499
1507
  failureCount: operationResult.failureCount,
1500
1508
  reportedFailureCount: reportedFailures.length,
@@ -1506,7 +1514,10 @@ export class TradingService {
1506
1514
  catch (error) {
1507
1515
  operationError =
1508
1516
  error instanceof Error ? error : new Error(String(error));
1509
- this.#deps.logger.error(ensureError(error, 'TradingService.cancelOrders'), this.#getErrorContext('cancelOrders'));
1517
+ this.#deps.logger.error(ensureError(error, 'TradingService.cancelOrders'), this.#getErrorContext(context, 'cancelOrders', {
1518
+ operation: PERPS_ERROR_OPERATION.OrderManagement,
1519
+ action: PERPS_ERROR_ACTION.CancelOrder,
1520
+ }));
1510
1521
  throw error;
1511
1522
  }
1512
1523
  finally {
@@ -1527,6 +1538,11 @@ export class TradingService {
1527
1538
  this.#deps.tracer.endTrace({
1528
1539
  name: PerpsTraceNames.CancelOrder,
1529
1540
  id: traceId,
1541
+ status: getTraceStatus(operationResult?.success),
1542
+ data: {
1543
+ success: operationResult?.success === true,
1544
+ ...(operationError ? { error: operationError.message } : {}),
1545
+ },
1530
1546
  });
1531
1547
  }
1532
1548
  }
@@ -1615,7 +1631,10 @@ export class TradingService {
1615
1631
  else {
1616
1632
  traceData = { success: false, error: result.error ?? 'Unknown error' };
1617
1633
  if (!isSignerUnavailable(result.error)) {
1618
- this.#deps.logger.error(ensureError(result.error, 'TradingService.closePosition'), this.#getErrorContext('closePosition', {
1634
+ this.#deps.logger.error(ensureError(result.error, 'TradingService.closePosition'), this.#getErrorContext(context, 'closePosition', {
1635
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
1636
+ action: PERPS_ERROR_ACTION.ClosePosition,
1637
+ }, {
1619
1638
  symbol: params.symbol,
1620
1639
  providerError: result.error ?? 'Unknown error',
1621
1640
  }));
@@ -1648,20 +1667,12 @@ export class TradingService {
1648
1667
  duration: completionDuration,
1649
1668
  bulkActionId,
1650
1669
  });
1651
- this.#deps.logger.error(ensureError(error, 'TradingService.closePosition'), {
1652
- tags: {
1653
- feature: PERPS_CONSTANTS.FeatureName,
1654
- provider: context.tracingContext.provider,
1655
- network: context.tracingContext.isTestnet ? 'testnet' : 'mainnet',
1656
- },
1657
- context: {
1658
- name: context.errorContext.controller,
1659
- data: {
1660
- method: context.errorContext.method,
1661
- symbol: params.symbol,
1662
- },
1663
- },
1664
- });
1670
+ this.#deps.logger.error(ensureError(error, 'TradingService.closePosition'), this.#getErrorContext(context, context.errorContext.method, {
1671
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
1672
+ action: PERPS_ERROR_ACTION.ClosePosition,
1673
+ }, {
1674
+ symbol: params.symbol,
1675
+ }));
1665
1676
  throw error;
1666
1677
  }
1667
1678
  finally {
@@ -1669,6 +1680,7 @@ export class TradingService {
1669
1680
  this.#deps.tracer.endTrace({
1670
1681
  name: PerpsTraceNames.ClosePosition,
1671
1682
  id: traceId,
1683
+ status: getTraceStatus(traceData?.success),
1672
1684
  data: traceData,
1673
1685
  });
1674
1686
  }
@@ -1786,7 +1798,10 @@ export class TradingService {
1786
1798
  const failureSummary = reportedFailures
1787
1799
  .map((result) => `${result.symbol}: ${result.error ?? 'Unknown error'}`)
1788
1800
  .join('; ');
1789
- this.#deps.logger.error(new Error(`closePositions batch failure: ${operationResult.failureCount}/${operationResult.results.length} failed (${reportedFailures.length} reported) - ${failureSummary}`), this.#getErrorContext('closePositions', {
1801
+ this.#deps.logger.error(new Error(`closePositions batch failure: ${operationResult.failureCount}/${operationResult.results.length} failed (${reportedFailures.length} reported) - ${failureSummary}`), this.#getErrorContext(context, 'closePositions', {
1802
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
1803
+ action: PERPS_ERROR_ACTION.ClosePosition,
1804
+ }, {
1790
1805
  successCount: operationResult.successCount,
1791
1806
  failureCount: operationResult.failureCount,
1792
1807
  reportedFailureCount: reportedFailures.length,
@@ -1799,7 +1814,10 @@ export class TradingService {
1799
1814
  catch (error) {
1800
1815
  operationError =
1801
1816
  error instanceof Error ? error : new Error(String(error));
1802
- this.#deps.logger.error(ensureError(error, 'TradingService.closePositions'), this.#getErrorContext('closePositions', {
1817
+ this.#deps.logger.error(ensureError(error, 'TradingService.closePositions'), this.#getErrorContext(context, 'closePositions', {
1818
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
1819
+ action: PERPS_ERROR_ACTION.ClosePosition,
1820
+ }, {
1803
1821
  symbols: params.symbols?.length ?? 0,
1804
1822
  closeAll: params.closeAll,
1805
1823
  }));
@@ -1829,6 +1847,11 @@ export class TradingService {
1829
1847
  this.#deps.tracer.endTrace({
1830
1848
  name: PerpsTraceNames.ClosePosition,
1831
1849
  id: traceId,
1850
+ status: getTraceStatus(operationResult?.success),
1851
+ data: {
1852
+ success: operationResult?.success === true,
1853
+ ...(operationError ? { error: operationError.message } : {}),
1854
+ },
1832
1855
  });
1833
1856
  }
1834
1857
  }
@@ -1935,7 +1958,10 @@ export class TradingService {
1935
1958
  catch (error) {
1936
1959
  errorMessage = error instanceof Error ? error.message : 'Unknown error';
1937
1960
  traceData = { success: false, error: errorMessage };
1938
- this.#deps.logger.error(ensureError(error, 'TradingService.updatePositionTPSL'), this.#getErrorContext('updatePositionTPSL', {
1961
+ this.#deps.logger.error(ensureError(error, 'TradingService.updatePositionTPSL'), this.#getErrorContext(context, 'updatePositionTPSL', {
1962
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
1963
+ action: PERPS_ERROR_ACTION.PositionTpslUpdate,
1964
+ }, {
1939
1965
  symbol: params.symbol,
1940
1966
  hasTakeProfit: Boolean(params.takeProfitPrice),
1941
1967
  hasStopLoss: Boolean(params.stopLossPrice),
@@ -2007,6 +2033,7 @@ export class TradingService {
2007
2033
  this.#deps.tracer.endTrace({
2008
2034
  name: PerpsTraceNames.UpdateTpsl,
2009
2035
  id: traceId,
2036
+ status: getTraceStatus(traceData?.success),
2010
2037
  data: traceData,
2011
2038
  });
2012
2039
  }
@@ -2078,6 +2105,7 @@ export class TradingService {
2078
2105
  this.#deps.tracer.endTrace({
2079
2106
  name: PerpsTraceNames.UpdateMargin,
2080
2107
  id: traceId,
2108
+ status: getTraceStatus(result.success),
2081
2109
  data: { success: result.success, error: result.error ?? '' },
2082
2110
  });
2083
2111
  return result;
@@ -2085,7 +2113,10 @@ export class TradingService {
2085
2113
  catch (error) {
2086
2114
  const completionDuration = this.#deps.performance.now() - startTime;
2087
2115
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
2088
- this.#deps.logger.error(ensureError(error, 'TradingService.updateMargin'), this.#getErrorContext('updateMargin', { symbol, amount }));
2116
+ this.#deps.logger.error(ensureError(error, 'TradingService.updateMargin'), this.#getErrorContext(context, 'updateMargin', {
2117
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
2118
+ action: PERPS_ERROR_ACTION.UpdateMargin,
2119
+ }, { symbol, amount }));
2089
2120
  // Track failure analytics
2090
2121
  this.#deps.metrics.trackPerpsEvent(PerpsAnalyticsEvent.RiskManagement, {
2091
2122
  [PERPS_EVENT_PROPERTY.STATUS]: PERPS_EVENT_VALUE.STATUS.FAILED,
@@ -2098,6 +2129,7 @@ export class TradingService {
2098
2129
  this.#deps.tracer.endTrace({
2099
2130
  name: PerpsTraceNames.UpdateMargin,
2100
2131
  id: traceId,
2132
+ status: 'error',
2101
2133
  data: { success: false, error: errorMessage },
2102
2134
  });
2103
2135
  throw error;
@@ -2150,6 +2182,10 @@ export class TradingService {
2150
2182
  size: flipSize.toString(),
2151
2183
  orderType: 'market',
2152
2184
  leverage: position.leverage?.value,
2185
+ // Lighter placeOrder otherwise logs order_management/place_order and
2186
+ // marks the result reported, which drops this flip from flip filters.
2187
+ // Close already suppresses that provider report. One Sentry event remains.
2188
+ deferProviderErrorReport: true,
2153
2189
  };
2154
2190
  // Emit submitted event before the provider round-trip, keeping flip
2155
2191
  // trades aligned with the consolidated placeOrder pipeline.
@@ -2233,10 +2269,21 @@ export class TradingService {
2233
2269
  }),
2234
2270
  ...this.#buildAttributionProperties(trackingData),
2235
2271
  });
2272
+ if (!isSilentFlipResult(result.error) &&
2273
+ !wasProviderErrorReported(result)) {
2274
+ this.#deps.logger.error(ensureError(result.error, 'TradingService.flipPosition'), this.#getErrorContext(context, 'flipPosition', {
2275
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
2276
+ action: PERPS_ERROR_ACTION.FlipPosition,
2277
+ }, {
2278
+ symbol: position.symbol,
2279
+ providerError: result.error ?? 'Unknown error',
2280
+ }));
2281
+ }
2236
2282
  }
2237
2283
  this.#deps.tracer.endTrace({
2238
2284
  name: PerpsTraceNames.FlipPosition,
2239
2285
  id: traceId,
2286
+ status: getTraceStatus(result.success),
2240
2287
  data: { success: result.success ?? false, error: result.error ?? '' },
2241
2288
  });
2242
2289
  return result;
@@ -2244,7 +2291,10 @@ export class TradingService {
2244
2291
  catch (error) {
2245
2292
  const completionDuration = this.#deps.performance.now() - startTime;
2246
2293
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
2247
- this.#deps.logger.error(ensureError(error, 'TradingService.flipPosition'), this.#getErrorContext('flipPosition', { symbol: position.symbol }));
2294
+ this.#deps.logger.error(ensureError(error, 'TradingService.flipPosition'), this.#getErrorContext(context, 'flipPosition', {
2295
+ operation: PERPS_ERROR_OPERATION.PositionManagement,
2296
+ action: PERPS_ERROR_ACTION.FlipPosition,
2297
+ }, { symbol: position.symbol }));
2248
2298
  // Track failure analytics with direction-specific flip action
2249
2299
  const wasLong = parseFloat(position.size) > 0;
2250
2300
  const failFlipAction = wasLong
@@ -2268,6 +2318,7 @@ export class TradingService {
2268
2318
  this.#deps.tracer.endTrace({
2269
2319
  name: PerpsTraceNames.FlipPosition,
2270
2320
  id: traceId,
2321
+ status: 'error',
2271
2322
  data: { success: false, error: errorMessage },
2272
2323
  });
2273
2324
  throw error;