Commit d99af47
authored
fix: perps activity reducer fires console.error on unhandled HL fill directions (Spot Dust Conversion) (#30174)
## **Description**
The perps activity reducer emits `console.error` for HL fills with
unrecognized `dir` values like "Spot Dust Conversion" (HL housekeeping —
auto-conversion of spot dust to USDC). This pollutes Sentry/dev console
and trips automated recipe gating. Fix adds explicit silent skip for
"Spot Dust Conversion" and downgrades the default unknown-direction
branch from `console.error` to `console.warn`.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes:
[TAT-3090](https://consensyssoftware.atlassian.net/browse/TAT-3090)
## **Manual testing steps**
```gherkin
Feature: Perps activity fill direction handling
Scenario: Spot Dust Conversion fills are silently skipped
Given a HL account with Spot Dust Conversion fill history
When the perps activity screen loads
Then no console.error is emitted for Spot Dust Conversion fills
And the fill is silently dropped from the activity list
Scenario: Unknown fill directions emit console.warn
Given a HL fill with an unrecognized direction string
When transformFillsToTransactions processes the fill
Then console.warn is emitted (not console.error)
And the fill is dropped from the result
```
## **Screenshots/Recordings**
No visual evidence selected for publication.
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **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.
## **Validation Recipe**
<details>
<summary>recipe.json</summary>
```json
{
"pr": "tat-3090",
"title": "Verify Spot Dust Conversion fills are silently skipped and unknown directions emit warn not error",
"jira": "TAT-3090",
"acceptance_criteria": [
"AC1: Fills with direction 'Spot Dust Conversion' are silently skipped without console.error",
"AC2: Fills with unknown direction emit console.warn instead of console.error",
"AC3: All previously handled directions continue to work correctly"
],
"validate": {
"static": ["yarn lint:tsc"],
"workflow": {
"pre_conditions": ["wallet.unlocked"],
"entry": "ac1-eval-dust-direction",
"nodes": {
"ac1-eval-dust-direction": {
"action": "eval_sync",
"expression": "(function(){ var d = 'Spot Dust Conversion'; var p1 = d.split(' ')[0]; var p2 = d.split(' ')[1]; var isOpen = p1 === 'Open'; var isClose = p1 === 'Close'; var isFlip = p2 === '>'; var isADL = d === 'Auto-Deleveraging'; var isBuy = d === 'Buy'; var isSell = d === 'Sell'; var isDust = d === 'Spot Dust Conversion'; var handled = isOpen || isClose || isFlip || isADL || isBuy || isSell || isDust; return JSON.stringify({direction: d, isDust: isDust, handled: handled, shouldSkipSilently: isDust}); })()",
"assert": {
"all": [
{ "operator": "eq", "field": "isDust", "value": true },
{ "operator": "eq", "field": "handled", "value": true },
{ "operator": "eq", "field": "shouldSkipSilently", "value": true }
]
},
"next": "ac2-eval-unknown-direction"
},
"ac2-eval-unknown-direction": {
"action": "eval_sync",
"expression": "(function(){ var d = 'TBD-NEW-HL-DIRECTION'; var p1 = d.split(' ')[0]; var p2 = d.split(' ')[1]; var isOpen = p1 === 'Open'; var isClose = p1 === 'Close'; var isFlip = p2 === '>'; var isADL = d === 'Auto-Deleveraging'; var isBuy = d === 'Buy'; var isSell = d === 'Sell'; var isDust = d === 'Spot Dust Conversion'; var handled = isOpen || isClose || isFlip || isADL || isBuy || isSell || isDust; return JSON.stringify({direction: d, handled: handled, shouldWarnNotError: !handled && !!d}); })()",
"assert": {
"all": [
{ "operator": "eq", "field": "handled", "value": false },
{ "operator": "eq", "field": "shouldWarnNotError", "value": true }
]
},
"next": "ac3-eval-known-directions"
},
"ac3-eval-known-directions": {
"action": "eval_sync",
"expression": "(function(){ var dirs = ['Open Long', 'Close Long', 'Open Short', 'Close Short', 'Long > Short', 'Short > Long', 'Auto-Deleveraging', 'Buy', 'Sell']; var results = []; for (var i = 0; i < dirs.length; i++) { var d = dirs[i]; var p1 = d.split(' ')[0]; var p2 = d.split(' ')[1]; var isOpen = p1 === 'Open'; var isClose = p1 === 'Close'; var isFlip = p2 === '>'; var isADL = d === 'Auto-Deleveraging'; var isBuy = d === 'Buy'; var isSell = d === 'Sell'; var handled = isOpen || isClose || isFlip || isADL || isBuy || isSell; results.push({dir: d, handled: handled}); } var allHandled = results.every(function(r){ return r.handled; }); return JSON.stringify({allHandled: allHandled, count: results.length}); })()",
"assert": {
"all": [
{ "operator": "eq", "field": "allHandled", "value": true },
{ "operator": "eq", "field": "count", "value": 9 }
]
},
"next": "teardown-done"
},
"teardown-done": {
"action": "end",
"status": "pass"
}
}
}
}
}
```
</details>
## **Recipe Workflow**
<details>
<summary>workflow.mmd</summary>
```mermaid
graph TD
ac1-eval-dust-direction["ac1-eval-dust-direction<br/>eval_sync: Spot Dust Conversion handled"] --> ac2-eval-unknown-direction
ac2-eval-unknown-direction["ac2-eval-unknown-direction<br/>eval_sync: unknown direction warn not error"] --> ac3-eval-known-directions
ac3-eval-known-directions["ac3-eval-known-directions<br/>eval_sync: all 9 known directions handled"] --> teardown-done
teardown-done["teardown-done<br/>end: pass"]
```
</details>
[TAT-3090]:
https://consensyssoftware.atlassian.net/browse/TAT-3090?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: only adjusts fill-direction handling and logging, plus adds
tests, without changing trade calculations for known directions.
>
> **Overview**
> Prevents noisy error logging when transforming HL fills into perps
activity transactions.
>
> `transformFillsToTransactions` now **silently skips** fills with
direction `Spot Dust Conversion`, and changes unknown/missing direction
handling from `console.error` to `console.warn` while continuing to drop
those fills.
>
> Adds unit tests asserting the skip behavior and that unknown/empty
directions warn (and never error).
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
982577b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent b30bd2a commit d99af47
2 files changed
Lines changed: 68 additions & 2 deletions
Lines changed: 63 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
768 | 768 | | |
769 | 769 | | |
770 | 770 | | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
771 | 834 | | |
772 | 835 | | |
773 | 836 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
308 | 308 | | |
309 | 309 | | |
310 | 310 | | |
311 | | - | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
312 | 315 | | |
313 | 316 | | |
314 | | - | |
| 317 | + | |
315 | 318 | | |
316 | 319 | | |
317 | 320 | | |
| |||
0 commit comments