Skip to content

🥅 server: handle no panda user on card create#791

Open
cruzdanilo wants to merge 1 commit intomainfrom
card
Open

🥅 server: handle no panda user on card create#791
cruzdanilo wants to merge 1 commit intomainfrom
card

Conversation

@cruzdanilo
Copy link
Member

@cruzdanilo cruzdanilo commented Feb 16, 2026


Open with Devin

Summary by CodeRabbit

  • Bug Fixes

    • Improved card creation to properly handle cases where the panda user account is not approved or not found, returning appropriate 403 error responses with clearer error codes.
  • Tests

    • Added test coverage for panda user account validation scenarios during card creation.

@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2026

🦋 Changeset detected

Latest commit: 5cd6f70

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@exactly/server Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@gemini-code-assist
Copy link

Summary of Changes

Hello @cruzdanilo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the server's card creation process by introducing robust error handling for unapproved Panda users. It ensures that when a user attempts to create a card but their associated Panda account lacks approval, the API responds with a precise 403 Forbidden status, providing clearer feedback and preventing unexpected system behavior. The changes also include a refactoring of error code constants for improved maintainability and new tests to cover these specific error conditions.

Highlights

  • Improved Error Handling for Unapproved Panda Users: Implemented specific error handling in the card creation flow to gracefully manage scenarios where a Panda user is not approved, returning a 403 Forbidden status with a clear 'no panda' error code.
  • Refactored Error Code Constants: Replaced the BadRequestCodes constant with direct string literals for error responses across the card.ts API, simplifying error code management.
  • Enhanced Panda API Error Parsing: Modified the createCard utility function to parse specific 403 error messages from the external Panda API, rethrowing a standardized 'panda user not approved' error for consistent handling.
  • Added Comprehensive Test Coverage: Introduced new test cases to validate the server's behavior when a Panda user is unapproved and when the createCard function encounters other types of 403 errors from the external service.
Changelog
  • .changeset/quiet-otter-map.md
    • Added a new changeset file for the patch.
  • server/api/card.ts
    • Removed the BadRequestCodes constant and replaced its usages with string literals.
    • Updated card creation logic to catch and handle 'panda user not approved' errors specifically, returning a 403 status.
  • server/test/api/card.test.ts
    • Added two new test cases to validate the server's response when a Panda user is unapproved.
    • Added a test case to ensure the server throws a 500 error for other unexpected 403 errors from the createCard function.
  • server/utils/panda.ts
    • Wrapped the request call in createCard with a try-catch block to parse 403 error messages from the Panda API.
    • Implemented logic to identify and rethrow a standardized 'panda user not approved' error if a specific message is matched.
Activity
  • The pull request was initiated.
  • Devin AI provided a review.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

Walkthrough

The changes implement error handling for missing or unapproved Panda users during card creation. The Panda utility now catches and normalizes specific API errors (403 user not approved, 404 user not found) into standardized "no user" errors. The Card API maps these to 403 responses with "no panda" code. New tests verify these error scenarios.

Changes

Cohort / File(s) Summary
Error Handling & Validation
server/utils/panda.ts, server/api/card.ts
Added try/catch wrapper in panda.ts to detect and normalize 403/404 Panda API errors into "no user" error. Updated card.ts to replace BadRequestCodes constant with inline string literals and handle "no panda" as 403 response via buildBaseResponse().
Test Coverage
server/test/api/card.test.ts
Added three new test cases for authenticated card creation: 403 when panda user not approved, 403 when panda user not found, and 500 when encountering other 403 errors from panda service.
Release Documentation
.changeset/calm-otter-map.md
Added patch version changeset entry documenting "handle no panda user on card create".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • nfmelendez
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: handling the no panda user scenario on card creation, which aligns with the refactoring across card.ts, panda.ts, and tests.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ 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 card

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.

@sentry
Copy link

sentry bot commented Feb 16, 2026

Sentry Issue: SERVER-J5

@sentry
Copy link

sentry bot commented Feb 16, 2026

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.83%. Comparing base (1f3e84f) to head (5cd6f70).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
server/api/card.ts 80.95% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #791      +/-   ##
==========================================
- Coverage   68.98%   68.83%   -0.16%     
==========================================
  Files         207      207              
  Lines        7032     7033       +1     
  Branches     2222     2223       +1     
==========================================
- Hits         4851     4841      -10     
- Misses       2000     2010      +10     
- Partials      181      182       +1     
Flag Coverage Δ
e2e 68.83% <80.95%> (+15.93%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly handles a specific user not approved error from the Panda API during card creation by returning a 403 status, including specific error parsing and new tests. No specific vulnerabilities or critical issues were found. There are a couple of suggestions to improve code maintainability and clarity.

I am having trouble creating individual review comments. Click here to see my feedback.

server/api/card.ts (48-53)

medium

The BadRequestCodes constant object was removed, and its values are now hardcoded as strings. Using constants for such values is generally better for maintainability as it prevents typos, provides a single source of truth, and makes the code easier to refactor. Since these codes are used in multiple places, I'd recommend re-introducing this constant object.

server/utils/panda.ts (71-93)

medium

The error handling logic in this catch block is a bit complex due to manual string parsing and variable declarations. This can be simplified for better readability and robustness, reducing the chance of bugs if the upstream error format changes slightly.

  } catch (error) {
    if (error instanceof Error) {
      const separator = error.message.indexOf(" ");
      if (separator !== -1) {
        const status = Number.parseInt(error.message.slice(0, separator), 10);
        if (status === 403) {
          try {
            const payload = JSON.parse(error.message.slice(separator + 1)) as { error?: string; message?: string };
            if (payload.error === "ForbiddenError" && payload.message === "User exists, but is not not approved") {
              throw new Error("panda user not approved");
            }
          } catch {
            // Not JSON or doesn't match, fall through to rethrow original error
          }
        }
      }
    }
    throw error;
  }

@sentry
Copy link

sentry bot commented Feb 16, 2026

Sentry Issue: SERVER-JC

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

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

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5cd6f707ad

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@cruzdanilo cruzdanilo changed the title 🥅 server: handle panda unapproved user on card create 🥅 server: handle no panda user on card create Feb 16, 2026
@sentry
Copy link

sentry bot commented Feb 16, 2026

Sentry Issue: SERVER-JE

2 similar comments
@sentry
Copy link

sentry bot commented Feb 16, 2026

Sentry Issue: SERVER-JE

@sentry
Copy link

sentry bot commented Feb 16, 2026

Sentry Issue: SERVER-JE

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/api/card.ts (1)

578-583: 🧹 Nitpick | 🔵 Trivial

buildBaseResponse creates an open string schema, not a literal constraint.

buildBaseResponse uses pipe(string(), metadata(...)) which accepts any string value. For response schemas where the code/legacy values are fixed (e.g., "bad request", "no panda", "already set"), consider using literal() to produce accurate OpenAPI documentation.

♻️ Suggested fix
-function buildBaseResponse(example = "string") {
+function buildBaseResponse(code: string) {
   return object({
-    code: pipe(string(), metadata({ examples: [example] })),
-    legacy: pipe(string(), metadata({ examples: [example] })),
+    code: pipe(literal(code), metadata({ examples: [code] })),
+    legacy: pipe(string(), metadata({ examples: [code] })),
   });
 }

Note: legacy is kept as string() since the actual legacy values differ from code in some cases (e.g., "panda id not found" vs "no panda").

const account = parse(Address, credential.account);
setUser({ id: account });
if (!credential.pandaId) return c.json({ code: BadRequestCodes.NO_PANDA, legacy: BadRequestCodes.NO_PANDA }, 403);
if (!credential.pandaId) return c.json({ code: "no panda", legacy: "no panda" }, 403);
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

🧩 Analysis chain

🏁 Script executed:

rg -n "panda id not found" --type=ts -g '!server/test/**'

Repository: exactly/exa

Length of output: 372


🏁 Script executed:

rg -n '"no panda"' --type=ts -g '!server/test/**'

Repository: exactly/exa

Length of output: 783


🏁 Script executed:

cat -n server/api/card.ts | sed -n '235,252p'

Repository: exactly/exa

Length of output: 1123


🏁 Script executed:

cat -n server/api/card.ts | sed -n '339,350p'

Repository: exactly/exa

Length of output: 662


🏁 Script executed:

cat -n server/api/card.ts | sed -n '413,420p'

Repository: exactly/exa

Length of output: 384


Inconsistent legacy field between GET and POST for the same "no panda" code.

GET handlers return legacy: "no panda" (lines 237, 250), while POST handlers return legacy: "panda id not found" (lines 341, 415). Unify these values unless the discrepancy is intentional for backward compatibility with existing clients.

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.

1 participant