You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[HOLD for payment 2024-02-07] [$500] IOU - Replacing Receipt with an Invalid File Format Does Not Display an Error Message #28343
Send a Money Request to another account, using the Scan Receipt option
Click on the Receipt image to open the preview popup
Click on the “Three dots” icon >> select the “Replace” option
Replace the current image with another image in an unsupported format, such as "webp"
Observe that: there is no error, but when reloading the page, the old image still appears (which indicates that new image is not uploaded)
Expected Result:
In this case, the user has uploaded an invalid image format, so there should be an error message. The file should remain optimistically in Onyx until the user decides to clear the error.
Actual Result:
No error displays.
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Android / native
Android / Chrome
iOS / native
iOS / Safari
MacOS / Chrome / Safari
MacOS / Desktop
Version Number: 1.3.74-2
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from TestRail:
changed the title [-]IOU - Replacing Receipt with an Invalid File Format Does Not Display an Error Message[/-][+][$500] IOU - Replacing Receipt with an Invalid File Format Does Not Display an Error Message[/+]on Sep 27, 2023
Please re-state the problem that we are trying to solve in this issue
The app allows the user to upload an invalid file format but then shows the old image.
What is the root cause of that problem?
If we want to forbid files with UNALLOWED_EXTENSIONS from being uploaded (front-end only fix, outdated):
The problem stems from the validateReceipt function located in the ReceiptSelector/index.js component:
function validateReceipt(file) {
const {fileExtension} = FileUtils.splitExtensionFromFileName(lodashGet(file, 'name', ''));
if (_.contains(CONST.API_ATTACHMENT_VALIDATIONS.UNALLOWED_EXTENSIONS, fileExtension.toLowerCase())) {
setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension');
return false;
}
...
In this case UNALLOWED_EXTENSION does not exist within CONST.API_ATTACHMENT_VALIDATIONS, therefore no file format is excluded from upload as receipt.
If we want to show an error message and for the file remain optimistically in Onyx until the user decides to clear the error (updated expected result):
The first problem comes from the fact that IOU.replaceReceipt function is currently getting the transaction by using lodashGet(allTransactions, 'transactionID', {}) which is not corrent because allTransactions is the main object which has keys starting with ransactions_{key} format, therefore transaction is always empty.
The second problem is that Onyx failureData is not being populated with errors when the ReplaceReceipt api call fails.
What changes do you think we should make in order to solve the problem?
Would add UNALLOWED_EXTENSION constant as an array of comma separated strings with the not-allowed formats (TBD).
If we want to show an error message and for the file remain optimistically in Onyx until the user decides to clear the error (updated expected result):
Within IOU.js we should add / change the following:
but we're getting transaction by using lodashGet(allTransactions, 'transactionID', {});, and it's wrong because allTransactions is the object and its keys have the transactions_{key} format, so transaction is always empty
and we don't add errors to failureData -> the error message is not shown
What changes do you think we should make in order to solve the problem?
We should defined UNALLOWED_EXTENSION in API_ATTACHMENT_VALIDATIONS
Add errors to OfflineWithFeedback, this props must be the object for now, but we need to render the component so we need to define the new props for OfflineWithFeedback to render the errors as the React component
Add ConfirmModal component that allow users download local file before dismiss the error
When we refresh app, the receipt and filename will be override from BE results (OpenReport API), but not errors. So we need BE fix to return errors: null
What alternative solutions did you explore? (Optional)
The solution for this issue has been 🚀 deployed to production 🚀 in version 1.4.34-1 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
[@hoangzinh] The PR that introduced the bug has been identified. Link to the PR:
[@hoangzinh] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
[@hoangzinh] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:
[@hoangzinh] Determine if we should create a regression test for this bug.
[@hoangzinh] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
[@trjExpensify] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:
The PR that introduced the bug has been identified. Link to the PR: the root cause is fixed so this PR is just a UI/UX improvement.
The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment: N/A
A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion: N/A
Determine if we should create a regression test for this bug. YES
If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
Regression Test Proposal
Login to any account
Send a Money Request to another account, using the Scan Receipt option
Click on the Receipt image to open the preview popup
Click on the “Three dots” icon >> select the “Replace” option
Replace the current image with an unsupported file. Ex: [CORRUPT.pdf (https://github.com/Expensify/App/files/13582924/CORRUPT.pdf)
Verify that the error message is shown and users can download the invalid file
Click clear error icon
Verify that the errors are removed, and the previous file is shown
Activity
[-]IOU - Replacing Receipt with an Invalid File Format Does Not Display an Error Message[/-][+][$500] IOU - Replacing Receipt with an Invalid File Format Does Not Display an Error Message[/+]melvin-bot commentedon Sep 27, 2023
Triggered auto assignment to @trjExpensify (
Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.melvin-bot commentedon Sep 27, 2023
Job added to Upwork: https://www.upwork.com/jobs/~01bb8307379994bc8e
melvin-bot commentedon Sep 27, 2023
Bug0 Triage Checklist (Main S/O)
Platformsin OP are ✅)melvin-bot commentedon Sep 27, 2023
Triggered auto assignment to Contributor-plus team member for initial proposal review - @hoangzinh (
External)ikevin127 commentedon Sep 27, 2023
Proposal - Updated
Please re-state the problem that we are trying to solve in this issue
The app allows the user to upload an invalid file format but then shows the old image.
What is the root cause of that problem?
If we want to forbid files with
UNALLOWED_EXTENSIONSfrom being uploaded (front-end only fix, outdated):The problem stems from the
validateReceiptfunction located in theReceiptSelector/index.jscomponent:In this case
UNALLOWED_EXTENSIONdoes not exist withinCONST.API_ATTACHMENT_VALIDATIONS, therefore no file format is excluded from upload as receipt.If we want to show an error message and for the file remain optimistically in Onyx until the user decides to clear the error (updated expected result):
The first problem comes from the fact that
IOU.replaceReceiptfunction is currently getting the transaction by usinglodashGet(allTransactions, 'transactionID', {})which is not corrent becauseallTransactionsis the main object which has keys starting withransactions_{key}format, thereforetransactionis always empty.The second problem is that Onyx
failureDatais not being populated with errors when theReplaceReceiptapi call fails.What changes do you think we should make in order to solve the problem?
Would add
UNALLOWED_EXTENSIONconstant as an array of comma separated strings with the not-allowed formats (TBD).If we want to show an error message and for the file remain optimistically in Onyx until the user decides to clear the error (updated expected result):
Within
IOU.jswe should add / change the following:Within
MoneyRequestView.jswe should add / change the following:Within
OfflineWithFeedback.jswe should change the following in order to add paddingspacing.ph5to the error:{props.shouldShowErrorMessages && hasErrorMessages && ( - <View style={StyleUtils.combineStyles(styles.offlineFeedback.error, props.errorRowStyles)}> + <View style={StyleUtils.combineStyles(styles.offlineFeedback.error, spacing.ph5, props.errorRowStyles)}> <DotIndicatorMessage style={[styles.flex1]} messages={errorMessages} type="error" /> <Tooltip text={translate('common.close')}> <PressableWithoutFeedback onPress={props.onClose} style={[styles.touchableButtonImage]} accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} accessibilityLabel={translate('common.close')} > <Icon src={Expensicons.Close} /> </PressableWithoutFeedback> </Tooltip> </View> )}What alternative solutions did you explore? (Optional)
N/A
Videos
web.mp4
tienifr commentedon Sep 28, 2023
Proposal
Please re-state the problem that we are trying to solve in this issue
IOU - Replacing Receipt with an Invalid File Format Does Not Display an Error Message
What is the root cause of that problem?
App/src/pages/iou/ReceiptSelector/index.js
Line 90 in 7ada99f
we're using
UNALLOWED_EXTENSIONS, but it's not in API_ATTACHMENT_VALIDATIONS -> no error message appearApp/src/libs/actions/IOU.js
Lines 2125 to 2127 in 7ada99f
but we're getting transaction by using
lodashGet(allTransactions, 'transactionID', {});, and it's wrong becauseallTransactionsis the object and its keys have thetransactions_{key}format, so transaction is always emptyand we don't add errors to failureData -> the error message is not shown
What changes do you think we should make in order to solve the problem?
Add errors to
OfflineWithFeedback, this props must be the object for now, but we need to render the component so we need to define the new props forOfflineWithFeedbackto render the errors as the React componentAdd
ConfirmModalcomponent that allow users download local file before dismiss the errorWhen we refresh app, the receipt and filename will be override from BE results (OpenReport API), but not
errors. So we need BE fix to returnerrors: nullWhat alternative solutions did you explore? (Optional)
None
Result
Screen.Recording.2023-10-09.at.14.32.18.mov
trjExpensify commentedon Sep 28, 2023
@JmillsExpensify @youssef-lr, how does this one jive with this issue for allowing all file extensions? Seems like we're silently failing in this case.
CC: @AndrewGable @Gonals as well from the receipt upload implementation
youssef-lr commentedon Sep 28, 2023
@trjExpensify the issue you linked is for attachments. We have some restrictions when it comes to what types of receipts you can upload I think.
143 remaining items
melvin-bot commentedon Jan 31, 2024
Reviewinglabel has been removed, please complete the "BugZero Checklist".melvin-bot commentedon Jan 31, 2024
The solution for this issue has been 🚀 deployed to production 🚀 in version 1.4.34-1 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2024-02-07. 🎊
For reference, here are some details about the assignees on this issue:
melvin-bot commentedon Jan 31, 2024
BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
trjExpensify commentedon Feb 9, 2024
👋 checklist time here!
hoangzinh commentedon Feb 10, 2024
BugZero Checklist:
Regression Test Proposal
Do we agree 👍 or 👎
melvin-bot commentedon Feb 13, 2024
@hoangzinh, @trjExpensify, @jasperhuangg, @tienifr Whoops! This issue is 2 days overdue. Let's get this updated quick!
jasperhuangg commentedon Feb 13, 2024
@hoangzinh those tests look good to me, thanks!
trjExpensify commentedon Feb 14, 2024
Nice, thanks! Applause have a regression test for the failed upload side, so I've created an issue for the replace receipt side.
trjExpensify commentedon Feb 14, 2024
Summarising payouts as follows:
Settled up, thanks!