Skip to content

[ENG-1623] Do not return error when pnl/parentSubaccountNumber returns empty array#3291

Merged
davidli1997 merged 7 commits intomainfrom
davidli/pnl_endpoint
Dec 19, 2025
Merged

[ENG-1623] Do not return error when pnl/parentSubaccountNumber returns empty array#3291
davidli1997 merged 7 commits intomainfrom
davidli/pnl_endpoint

Conversation

@davidli1997
Copy link
Contributor

@davidli1997 davidli1997 commented Dec 19, 2025

Changelist

Fix /v4/pnl/parentSubaccountNumber endpoint to return empty array instead of error when no PNL data matches filters

  • Removed the NotFoundError check when pnlData.results.length === 0 - now returns {"pnl":[]} instead of an error
  • Added subaccount existence check at the start of the endpoint - returns 404 only if the parent subaccount doesn't exist at all
  • This fixes the issue where queries with createdBeforeOrAt filter that excluded all data would return an error instead of an empty array

Test Plan

Added controller tests:

  • Get /pnl/parentSubaccountNumber returns empty array when date filter excludes all data - verifies both daily and hourly endpoints return 200 with empty array when createdBeforeOrAt excludes all records
  • Get /pnl/parentSubaccountNumber returns empty array when no PNL records exist - verifies empty array is returned when subaccount exists but has no PNL data
  • Updated Get /pnl/parentSubaccountNumber with non-existent address returns 404 - verifies 404 is still returned for non-existent addresses

Tested in staging,
before:
Screenshot 2025-12-19 at 12 53 14 PM
after:
Screenshot 2025-12-19 at 1 03 01 PM

Author/Reviewer Checklist

  • If this PR has changes that result in a different app state given the same prior state and transaction list, manually add the state-breaking label.
  • If the PR has breaking postgres changes to the indexer add the indexer-postgres-breaking label.
  • If this PR isn't state-breaking but has changes that modify behavior in PrepareProposal or ProcessProposal, manually add the label proposal-breaking.
  • If this PR is one of many that implement a specific feature, manually label them all feature:[feature-name].
  • If you wish to for mergify-bot to automatically create a PR to backport your change to a release branch, manually add the label backport/[branch-name].
  • Manually add any of the following labels: refactor, chore, bug.

@davidli1997 davidli1997 requested a review from a team as a code owner December 19, 2025 17:41
@linear
Copy link

linear bot commented Dec 19, 2025

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Walkthrough

This PR adds test coverage for empty PnL dataset scenarios and refactors the parent subaccount PnL endpoint to validate subaccount existence upfront while allowing empty results without error, replacing previous error-throwing behavior for missing PnL data.

Changes

Cohort / File(s) Summary
GitHub Actions trigger
.github/workflows/indexer-build-and-push-dev-staging.yml
Added branch pattern davidli/pnl_endpoint to workflow push trigger.
PnL store tests
indexer/packages/postgres/__tests__/stores/pnl-table.test.ts
Added two test cases verifying that findAllHourlyAggregate and findAllDailyAggregate return empty arrays when no data exists for multiple subaccounts.
PnL controller tests
indexer/services/comlink/__tests__/controllers/api/v4/pnl-controller.test.ts
Updated error message expectation and added new tests for GET /pnl/parentSubaccountNumber endpoint covering empty-result scenarios (date filters excluding all data and no records present).
PnL controller logic
indexer/services/comlink/src/controllers/api/v4/pnl-controller.ts
Added parent subaccount existence pre-check in getPnlForParentSubaccount and changed behavior to return empty results instead of throwing error when no PnL data exists.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Main logic change is localized to one function (getPnlForParentSubaccount) with straightforward pre-check addition and error-handling modification
  • Test additions follow consistent patterns across multiple files
  • Changes involve minimal cross-file dependencies

Possibly related PRs

Suggested reviewers

  • tqin7
  • shrenujb

Poem

🐰 A parent's check, before PnL appears,
No errors now when data disappears—
Just empty arrays, honestly clear,
Tests prove the path, with patience sincere,
The endpoint hops on, without fear!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main behavioral change: modifying the pnl/parentSubaccountNumber endpoint to return an empty array instead of throwing an error when no PnL data exists.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed PR description includes complete changelist, test plan with specific test cases, and author/reviewer checklist as required by template.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch davidli/pnl_endpoint

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

@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: 0

🧹 Nitpick comments (2)
.github/workflows/indexer-build-and-push-dev-staging.yml (1)

5-9: Avoid hard‑coding a personal feature branch in shared workflow triggers

Adding davidli/pnl_endpoint is fine for local experimentation, but it’s usually better to:

  • Either remove this entry before merge, or
  • Replace it with a generic pattern (e.g. feature/*) if you want workflows on many feature branches.

Otherwise the workflow config accumulates stale, one-off branch names over time.

indexer/packages/postgres/__tests__/stores/pnl-table.test.ts (1)

857-919: Empty‑result coverage for hourly/daily aggregates is solid

Both tests correctly distinguish:

  • No matches due to a restrictive createdBeforeOrAt filter, and
  • No PnL rows at all for valid subaccount IDs.

They verify that findAllHourlyAggregate/findAllDailyAggregate return results: [] instead of erroring, which lines up with the new API behavior. If you want to extend coverage later, you could also assert total/offset for these empty cases, but the current assertions are sufficient for the regression you’re targeting.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d227095 and 2e6ae62.

📒 Files selected for processing (4)
  • .github/workflows/indexer-build-and-push-dev-staging.yml (1 hunks)
  • indexer/packages/postgres/__tests__/stores/pnl-table.test.ts (1 hunks)
  • indexer/services/comlink/__tests__/controllers/api/v4/pnl-controller.test.ts (2 hunks)
  • indexer/services/comlink/src/controllers/api/v4/pnl-controller.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: hwray
Repo: dydxprotocol/v4-chain PR: 2597
File: indexer/services/ender/src/scripts/handlers/dydx_update_perpetual_v1_handler.sql:16-20
Timestamp: 2024-11-22T18:12:04.606Z
Learning: Avoid suggesting changes to deprecated functions such as `dydx_update_perpetual_v1_handler` in `indexer/services/ender/src/scripts/handlers/dydx_update_perpetual_v1_handler.sql` if they are unchanged in the PR.
🧬 Code graph analysis (3)
indexer/services/comlink/src/controllers/api/v4/pnl-controller.ts (2)
indexer/packages/redis/__tests__/caches/constants.ts (1)
  • address (15-15)
indexer/services/comlink/src/lib/errors.ts (1)
  • NotFoundError (15-20)
indexer/services/comlink/__tests__/controllers/api/v4/pnl-controller.test.ts (1)
indexer/services/comlink/__tests__/helpers/helpers.ts (2)
  • sendRequest (82-106)
  • getQueryString (108-121)
indexer/packages/postgres/__tests__/stores/pnl-table.test.ts (1)
indexer/packages/postgres/__tests__/helpers/constants.ts (3)
  • defaultSubaccountId (156-159)
  • defaultSubaccountId2 (160-163)
  • defaultPnl (1125-1132)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (39)
  • GitHub Check: lint
  • GitHub Check: call-build-ecs-service-ender / (ender) Check docker image build
  • GitHub Check: call-build-ecs-service-comlink / (comlink) Check docker image build
  • GitHub Check: check-build-auxo
  • GitHub Check: check-build-bazooka
  • GitHub Check: call-build-ecs-service-roundtable / (roundtable) Check docker image build
  • GitHub Check: test / run_command
  • GitHub Check: (Public Testnet) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Public Testnet) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Mainnet) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Public Testnet) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: (Mainnet) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Public Testnet) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: (Public Testnet) Build and Push ECS Services / call-build-and-push-ecs-service-ender / (ender) Build and Push
  • GitHub Check: (Mainnet) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Public Testnet) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Mainnet) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: build-and-push-testnet
  • GitHub Check: run_command
  • GitHub Check: build-and-push-mainnet
  • GitHub Check: Analyze (go)
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: (Dev) Build and Push ECS Services / call-build-and-push-auxo-lambda / (auxo) Build and Push Lambda
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-ecs-service-ender / (ender) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-vulcan / (vulcan) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-roundtable / (roundtable) Build and Push
  • GitHub Check: (Dev4) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Dev2) Build and Push ECS Services / call-build-and-push-ecs-service-socks / (socks) Build and Push
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-bazooka-lambda / (bazooka) Build and Push Lambda
  • GitHub Check: (Staging) Build and Push ECS Services / call-build-and-push-ecs-service-comlink / (comlink) Build and Push
  • GitHub Check: Summary
🔇 Additional comments (4)
indexer/services/comlink/src/controllers/api/v4/pnl-controller.ts (1)

129-137: Parent subaccount existence check and 404 semantics look correct

Checking SubaccountTable.findById up front and throwing NotFoundError only when the parent subaccount row is missing cleanly separates:

  • “Bad input” (non-existent parent subaccount → 404), from
  • “No data yet” (existing parent with zero PnL → empty pnl array and 200).

The error message matches the updated test expectation and the behavior is consistent with the single‑subaccount /pnl endpoint.

indexer/services/comlink/__tests__/controllers/api/v4/pnl-controller.test.ts (3)

979-985: Updated 404 expectation matches controller error contract

The new expected message:

'No subaccount found with address nonexistentaddress and parentSubaccountNumber 0'

is consistent with the NotFoundError thrown in getPnlForParentSubaccount, so this test now accurately reflects the endpoint’s contract for non‑existent parents.


1226-1279: Good regression coverage for date‑filtered empty parent‑subaccount PnL

This test properly verifies that when all PnL records fall after createdBeforeOrAt, /pnl/parentSubaccountNumber:

  • Returns HTTP 200, and
  • Returns pnl: [] for both daily=true and daily=false.

That directly guards against the previous behavior where “no rows after filtering” was treated as an error.


1281-1311: Clear test for “no PnL yet” on an existing parent subaccount

By seeding subaccounts but not inserting any PnL rows, then asserting 200 + pnl: [] for both daily and hourly calls, this test ensures:

  • Existing parent subaccounts no longer yield 404 purely due to missing PnL, and
  • Behavior is consistent across aggregation modes.

The setup and assertions look correct and align tightly with the PR objective.

@davidli1997
Copy link
Contributor Author

https://github.com/Mergifyio backport release/indexer/v9.x

@mergify
Copy link
Contributor

mergify bot commented Dec 19, 2025

backport release/indexer/v9.x

✅ Backports have been created

Details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants