Skip to content

Chore Uber: Add error handling, update empty list - #71241

Merged
iwiznia merged 15 commits into
Expensify:mainfrom
callstack-internal:feat/waterim/71196-71100
Sep 29, 2025
Merged

Chore Uber: Add error handling, update empty list#71241
iwiznia merged 15 commits into
Expensify:mainfrom
callstack-internal:feat/waterim/71196-71100

Conversation

@waterim

@waterim waterim commented Sep 24, 2025

Copy link
Copy Markdown
Contributor

Details

Fixed Issues

$ #71196
$ #71100

Tests

Test 1:

  1. Go to workspace
  2. Enable receipt partners
  3. Click on connect to uber
  4. Create a new organization in uber
  5. go back to expensify app
  6. Click on the "Manage invites"
  7. Enable "failing requests"
  8. Click invite
  9. You will see error under the user you tried to invite
  10. Click "X" to dismiss
  • Verify that no errors appear in the JS console

Offline tests

QA Steps

Same as tests

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android / native
    • Android / Chrome
    • iOS / native
    • iOS / Safari
    • MacOS / Chrome / Safari
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that the left part of a conditional rendering a React component is a boolean and NOT a string, e.g. myBool && <MyComponent />.
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I verified the translation was requested/reviewed in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is approved by marketing by adding the Waiting for Copy label for a copy review on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • If we are not using the full Onyx data that we loaded, I've added the proper selector in order to ensure the component only re-renders when the data it is using changes
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG))
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp image image
Android: mWeb Chrome
iOS: HybridApp
iOS: mWeb Safari image image
MacOS: Chrome / Safari image image
MacOS: Desktop image image

@waterim
waterim requested review from a team as code owners September 24, 2025 20:46
@melvin-bot
melvin-bot Bot requested review from dukenv0307 and removed request for a team September 24, 2025 20:46
@melvin-bot

melvin-bot Bot commented Sep 24, 2025

Copy link
Copy Markdown

@dukenv0307 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@codecov

codecov Bot commented Sep 24, 2025

Copy link
Copy Markdown

@trjExpensify

Copy link
Copy Markdown
Contributor

@dukenv0307 can you get to this one today? Thanks!

@dubielzyk-expensify

Copy link
Copy Markdown
Contributor

cc @dannymcclain for confirmation on the error message

Comment thread src/libs/actions/Policy/Policy.ts Outdated
receiptPartners: {
uber: {
employees: {
[email]: null,

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.

This would clear all the data, not just the error, no?

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.

agree, we just need to clear the errors only

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.

Screenshot 2025-09-25 at 10 32 54

is it really incorrect to remove the whole data? If we just clear error - user row will be with resent button - is it what we expect? @iwiznia
Screenshot 2025-09-25 at 10 34 46

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.

It needs to go back to the same state it was before the failure, no?

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.

prev state was empty object - same as we get after doing this [email]: null,

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.

It was? Don't we use this for resending invitations too?
In any case if this is correct, the name is not since the method is not clearing the error in an uber employee, it's clearing the whole employee

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.

hmm - ok we should just remove errors object from screenshot i posted above - is it right?

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.

Yeah

@trjExpensify

Copy link
Copy Markdown
Contributor

Ah yeah, this copy is a bit wonky.

image

Why plural? Would there be an error per member you clicked Invite || Resend on? If so, can we update the copy to:

Failed to invite member to Uber for Business

@dukenv0307

Copy link
Copy Markdown
Contributor

@dukenv0307 can you get to this one today? Thanks!

Yes, on it now

@dukenv0307

Copy link
Copy Markdown
Contributor

I think the padding is not correct here, it's 40px

Screenshot 2025-09-25 at 09 30 51

but I think it should be 16px like this

Screenshot 2025-09-25 at 09 31 29

Wdyt? @Expensify/design

@dukenv0307

Copy link
Copy Markdown
Contributor

The rest looks good

@trjExpensify

Copy link
Copy Markdown
Contributor

@narefyev91 confirming you updated the padding to match @dukenv0307's suggestion? CC: @dubielzyk-expensify for a quick look on APAC time, so @dukenv0307 can do a final review.

@dubielzyk-expensify

Copy link
Copy Markdown
Contributor

I don't think we have a standardized thing on these pages funnily enough. We use 20px from the edge usually as our default, so both are technically wrong. Sometimes we add a bit more padding to ensure the text looks balanced. And other screens have 16px etc.

Long way of saying that we don't have any super consistent treatment here. I'd probably say leave as is for now or update to 20px. Would be curious to hear if @Expensify/design thinks we should standardize here (could end up with some wonky text if we do though).

@shawnborton

Copy link
Copy Markdown
Contributor

Yeah, agree with all of your thinking. I think the most consistent thing to do is maybe keep 20px of padding on the outer-most wrapper. And then the empty state item itself might have another 20px of padding to help with the text wrapping if needed? But when in doubt, a simple 20px of padding is likely the most consistent thing to do.

The most ideal thing to do would be to have CSS's equivalent of text-wrap: balance, check it out here. I don't know that it is supported in RN though, we'd need some kind of package for it and I'm not sure it's worth it.

@narefyev91

Copy link
Copy Markdown
Contributor

@shawnborton @dubielzyk-expensify to summarise - for now we just add 20px padding and that's it?

# Conflicts:
#	src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx
#	src/pages/workspace/receiptPartners/utils.tsx
@shawnborton

Copy link
Copy Markdown
Contributor

I say do that and then show us how it looks. We can adjust after that if needed.

@narefyev91

narefyev91 commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

I also add in current PR logic for show broken connection #71195 @iwiznia @trjExpensify
Screenshot 2025-09-25 at 19 19 15

@shawnborton

Copy link
Copy Markdown
Contributor

Can you try adding like 8px of margin above the red text so we get some separation from the UI above it?

@narefyev91

Copy link
Copy Markdown
Contributor

I say do that and then show us how it looks. We can adjust after that if needed.

Sure - this is for 20px paddings @shawnborton
Screenshot 2025-09-26 at 12 27 28

@shawnborton

Copy link
Copy Markdown
Contributor

Cool, I think that's probably fine? Again, would be nice if the two lines were more balanced but I'm not sure if it's worth the hassle.

@narefyev91

Copy link
Copy Markdown
Contributor

Can you try adding like 8px of margin above the red text so we get some separation from the UI above it?

Updated as well:
Screenshot 2025-09-26 at 12 37 03

@shawnborton

Copy link
Copy Markdown
Contributor

Okay, let's see what @dannymcclain thinks, but I wonder if 12px or 16px would be better... it still feels a little crammed in there.

@dannymcclain

Copy link
Copy Markdown
Contributor

Let's go with 12px on the error message - I Agree with Shawn that it still feels a little tight because all we have going on in that row.

Sure - this is for 20px paddings

20px looks fine by me. I agree it'd be nice to have them more balanced, but it's not worth creating custom styles here. Let's just stick with 20px.

One question though - in your screenshot you're showing the Linked tab but that empty state is really just for Outstanding (the copy directly references outstanding invites 😅). Do we need another empty state for linked? If we want to reuse it for both, we should update the copy to be more generic. cc @trjExpensify

@trjExpensify

Copy link
Copy Markdown
Contributor

Mhm, I don't think it's possible. Minimally there's one person on the workspace and connected to U4B.

@dannymcclain

Copy link
Copy Markdown
Contributor

Ok cool. Just wanted to make sure!

@dukenv0307

Copy link
Copy Markdown
Contributor

Looks good, thanks everyone. Will do the checklist now

@dukenv0307

Copy link
Copy Markdown
Contributor

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
    • MacOS: Desktop
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
Screen.Recording.2025-09-26.at.23.07.08.mov
Android: mWeb Chrome
Screen.Recording.2025-09-26.at.23.01.14.mov
iOS: HybridApp
iOS: mWeb Safari
Screen.Recording.2025-09-26.at.22.59.29.mov
MacOS: Chrome / Safari
Screen.Recording.2025-09-26.at.22.55.09.mov
MacOS: Desktop
Screen.Recording.2025-09-26.at.23.07.45.mov

acc[email] = null;
// Build map for resetting employees on failure with individual errors
const resetEmployeesOnFailure = emails.reduce<Record<string, {status?: string; errors: Errors}>>((acc, email) => {
acc[email] = {

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.

we should reset the pendingFields in failureData as well.

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.

@dukenv0307 updated!

@dukenv0307

Copy link
Copy Markdown
Contributor

@narefyev91 Almost done, just left 1 comment

@melvin-bot
melvin-bot Bot requested a review from iwiznia September 29, 2025 08:48
@iwiznia
iwiznia merged commit 752c6a1 into Expensify:main Sep 29, 2025
22 checks passed
@OSBotify

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/iwiznia in version: 9.2.20-0 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/Julesssss in version: 9.2.20-4 🚀

platform result
🖥 desktop 🖥 success ✅
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

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.

9 participants