Power Apps Patch Function Error Handling
If you Patch records to a datasource and don’t check it for errors, you are doing it wrong! Why? Patching a record doesn’t guarantee it was successfully added/updated. There might have been a data validation issue, a dropped internet connection, not enough user permissions, or something else. Your users will continue using the app unaware there was a problem potentially leading to data loss. In this article I will show you how to perform patch function Error Handling In Power Apps.
Table of Contents:
Introduction: Test Scores App
SharePoint List Setup
Patching A New Record
Showing A Successful Patch
Error Handling With The ERRORS Function
Building A More Helpful Error Message
Validating A Record Before Patching
Introduction: Test Scores App
The Test Scores App is used by teachers at a high school to record student test scores. All tests must have a score between 0 and 100. If the score is successfully saved then the teacher sees a success message. But if there is an error the teacher sees a warning message and is not able to go to the next screen.
SharePoint List Setup
Create a new SharePoint list called test scores with the following columns:
- TestName (single-line text)
- StudentName (single-line text)
- Score (number)
Once some data gets submitted from the app it will eventually look like this but you won’t need to create any rows initially.
Scores must be a value between 0 and 100. Edit the Score column and set the minimum/maximum values as shown below.
Patching A New Record
Now lets shift over to making the canvas app. Open Power Apps Studio and create a new app from blank and name the 1st screen Submit Test Score. Insert a set of labels and text inputs for the Test Name, Student Name & Score as shown below. Place a submit button beneath them.
Pressing the submit button will create a new record in SharePoint. Write this code in the OnSelect property of the button. You’ll see an error in the navigate function because we haven’t made the Success Screen yet. We’ll do this next.
// create a new record in test scores list
Patch(
'Test Scores',
Defaults('Test Scores'),
{
TestName: txt_TestName.Text,
StudentName: txt_StudentName.Text,
Score: Value(txt_Score.Text)
}
);
// go to the success screen
Navigate('Success Screen');
Showing A Successful Patch
When a new record is successfully patched to SharePoint the teacher is allowed to go to the next screen. Insert a new Success screen from the pre-built options.
Rename the screen Success Screen.
Now when the submit button is clicked on the Submit Test Score the teacher will be taken to the Success Screen.
Error Handling With The ERRORS Function
We only want the Success Screen to show if the new record was successfully created in SharePoint. With our current code that will not happen. If the patch function fails the teacher would still be taken to the next screen. Instead, we want the teacher to see an error message and remain on the same screen so they can make any necessary changes and try again.
We can do this by making the following changes to the submit button’s OnSelect property. First, we use the Errors function to check if there were any problems during the latest patch. Errors outputs a table so we’ll evaluate it using the IsEmpty function. Then we’ll use the Notify function to display an error message saying “Test score submission failed.”
// create a new record in test scores list
Patch(
'Test Scores',
Defaults('Test Scores'),
{
TestName: txt_TestName.Text,
StudentName: txt_StudentName.Text,
Score: Value(txt_Score.Text)
}
);
If(
// check if there were any errors when the test score was submitted
!IsEmpty(Errors('Test Scores')),
// if true, show any error message
Notify(
"Test score submission failed",
NotificationType.Error
),
// else, go to success screen
Navigate('Success Screen');
)
A note about how the Errors function works: each time Patch is used on a datasource it error state gets reset. Therefore, Errors only returns errors resulting from the latest operation on the Test Scores SharePoint list. It does not cumulatively track all of the errors flagged while the app is in use. If that’s how Errors works then why does it output table? A table is needed because a single record can have more than one error (example: 2 columns with incorrect values).
Building A More Helpful Error Message
We now have an error message in place but it doesn’t tell the teacher why saving the test score failed. A more descriptive error message would help! Fortunately, the Errors function returns a table with these columns containing information about why the operation failed.
- Column – name of the column that failed.
- Message – why the error failed.
- Error – type of error
- Record – the complete record that failed update in the database. This will always be blank when creating a record.
To improve the error message, update the submit button’s OnSelect property as shown below. Notice how the Errors function is now inside a Concat function. This allows multiple error messages to be shown if there are more than one.
Patch(
'Test Scores',
Defaults('Test Scores'),
{
TestName: txt_TestName.Text,
StudentName: txt_StudentName.Text,
Score: Value(txt_Score.Text)
}
);
If(
// check if there were any errors when the test score was submitted
!IsEmpty(Errors('Test Scores')),
// if true, show any error message
Notify(
Concat(Errors('Test Scores'), Column&": "&Message),
NotificationType.Error
),
// else, go to success screen
Navigate('Success Screen');
)
Input an invalid score and try to submit the form again. Now you’ll see an error message showing why the new record was rejected and what column needs to be fixed.
Validating A Record Before Patching
No one likes getting and error message. So its a good practice to prevent the teacher from submitting an invalid record and failing. We can do this by disabling the submit button when the Score value is falls outside of the required range as shown below.
We’ll use the little-known Validate function to make it easy. Validate checks a record against a datasource and returns any error information without trying to create/update the datasource. When there’s no issues, it returns blank.
Put this code inside the submit button’s DisplayMode property.
If(
IsBlank(
Validate(
'Test Scores',
Defaults('Test Scores'),
{
TestName: txt_TestName.Text,
StudentName: txt_StudentName.Text,
Score: Value(txt_Score.Text)
}
)
),
DisplayMode.Edit,
DisplayMode.Disabled
)
We can also take this a step further and highlight the problematic value by using another variation of the Validate function.
Use this code inside the BorderColor property of the text input for Score. You’ll notice this code is working differently from the ‘disable submit button’ code so I recommend you check out the official Validate function documentation for more info on why.
If(
IsBlank(
Validate(
'Test Scores',
"Score",
IfError(Value(txt_Score.Text), 0)
)
),
RGBA(166, 166, 166, 1),
Red
)
Also, we’ve used the IfError function in the code above. In order for it to function properly you will need to enable the Formula-level error management setting. It says the feature is experimental, but don’t worry, I’ve tested this setting and its OK to use.
Great! Now we have a way to pre-check records before submission and have created a better experience for the teacher using the app. Keep in mind, even though the Validate function can tell us whether a record is valid it can’t anticipate every type of error. We still need to check for errors when using Patch.
Did You Enjoy This Article? 😺
Subscribe to get new Power Apps articles sent to your inbox each week for FREE
Questions?
If you have any questions or feedback about Power Apps Patch Function Error Handling please leave a message in the comments section below. You can post using your email address and are not required to create an account to join the discussion.
Woww!! What exactly i was looking for! I am going to refer this again and again
Ramesh,
We must have a psychic connection or something 😉
As always a very useful and informative post. Great examples!. Thanks Matt
You’re welcome Bill. Thanks for reading 🙂
I love this solution! I don’t usually use the Patch function because of the issues I’ve had with it. This is brilliant!
Valerie,
Patch is a tricky function. I purposely avoided it for the first 4 months of learning Power Apps. Its not the most intuitive thing ever… but now I use PATCH all the time.
What difficulties were you having?
I love this solution. Thanks Matt.
In a screen I have one edit form and 4 galleries. I want to save galleries data to SharePoint list after successful submission of edit form. Can you please tell me how to write validation for this scenario.
Sudheer,
What do you mean by ‘save galleries data’? Are you trying to patch all of the records in a collection into a datasource?
I can picture the edit form but I don’t know how the galleries fit in. How are these records related to the form? I’m only looking for a basic description here, not the entire scenario.
This is great, thanks. Only problem is the link to the official documentation seems to be broken
John,
Fixed. Thank for reporting the dead link!
A very helpful post. Thanks for highlighting the validate function, especially!
The link to the official documentation for the function doesn’t appear to be quite right for me.
Daniel,
I fixed it thanks to your post 🙂
Hey Matt,
In a scenario am patching form values to List A, B and C. Values from form are taken as per columns I defined in those respective lists. I have 2 questions here
Very useful as always Matt!
Awesome post! Do you have any tips on how to check if the Office365Outlook.SendEmailV2 actually sent out a mail? That’s typically the only other background task I use besides the Patch function to work on SP lists.
Jan,
If tracking is required I would suggest you send the emails using Power Automate instead of from Power Apps. Why? You can only check if an email was requested to be sent from Power Apps but you cannot see if the mail server actually sent it. Instead, if you send an email using a Flow you could write all the successful emails back to a datasource and even the status ones that didn’t using its error handling techniques.
Matthew,
thanks for your response. That’s a pity. I love how easy it is to send standardized mails from PowerApps. That’s why I use them. I prefer the code style PowerApps allows vs. the GUI driven Power Automate.
I found a tip to use “Connections.Connected” to verify the user connections are working properly. I guess I will go with that for the time being. But in the long run, I would expect Microsoft to provide a decent error-handling for this.
Keep up the great work!
This is great! Thank you so much for sharing Matthew! I use Patch all the time and will implement this method in all my apps.
Superb article. I wonder if there’s a way to adapt this technique when invoking a flow from PowerApps… that would be stellar.
Jake,
You might be able to use the IfError function to detect when the flow fails. Suggest you give it a shot 🙂
Wow! this is my first time I read an article here, and I’m very impressed. Simple and potent!
Gus,
Glad you enjoyed it. There’s a few other gems around here. If you look at the sidebar I’ve got a list of the most popular articles. It’s a good place to start.
Hi Matthew, great article your top 10 of 2021 pointed me to it.
Can I use this error check when patching multiple lines into a SharePoint list? I have a simple check list app for back up logs, the data I’m patching is all on a Canvas and my codes states which data cards need to be patched to which SharePoint column so the button onselect patches all at the same time. Hope that made sense.
Great Post Thanks Matt. As always a very useful and insightfull post. My only question is how the Errors works and with what syntax in a Patch with ForAll for multiple records?
Best Regards
Alexandros,
You could add the errors to a collection during each iteration of the loop and then write an IF statement afterwards to display the errors if colErrorMessage is not empty.
Clear(colErrorMessages);
ForAll(
Sequence(5), // example that creates 5 new records
Patch(
'Test Scores',
Defaults('Test Scores'),
{
TestName: txt_TestName.Text,
StudentName: txt_StudentName.Text,
Score: Value(txt_Score.Text)
}
);
If(
// check if there were any errors when the test score was submitted
!IsEmpty(Errors('Test Scores')),
// if true, show any error message
Collect(
colErrorMessages,
{Value: Concat(Errors('Test Scores'), Column&": "&Message)}
)
)
);
Hi Matthew! I have an app connected to a SharePoint library and if the user does not close the document, the patch function will fail. Do you have any idea how can I catch in PowerApps the error “The file …..is locked for shared use by…”?
Thank you
Claudia,
Maybe you could try the IfError() function as a potential solution
https://docs.microsoft.com/en-us/power-apps/maker/canvas-apps/functions/function-iferror
Thank you for this article, it has been very helpful. I am running into an issue, where the error message that is displayed is a higher level than what I am wanting to display. Rather than getting the details of the error, all that is returned is a generic message that there was an invalid operation. Included is a screenshot showing the error message that is displayed (highlighted in green) and the message that I would like to display (highlighted in red). Is it possible to get the more error message?
James,
That error message you highlighted has a type of “unhandled error.” There’s a new method for surfacing error information I’d like you to try using the IfError function.
Can you please take a look at this article and try to wrap the PATCH function inside an IFERROR function instead? Then you can use the FIRSTERROR property to extract the error Message, Kind, Column and other details.
https://www.matthewdevaney.com/power-apps-onerror-property-capture-log-unexpected-errors/
Also, what datasource are you writing back to? SharePoint? Google Sheets? Something else?
Tested with IfError and firstError and you will get the httpResponse message. Here is a way to get only the text without the client RequestId stuff (Need to activate the experimental ParseJSON)
Notify(First(Split(ParseJSON(FirstError.Details.HttpResponse).message;”clientRequestId:”).Result).Result; NotificationType.Error);
Martin,
Thanks for the helpful note!
This was very useful. I have a query on Text recognizer, how do i patch back the text identified to dataverse in that each data can be in the right column. At the moment the data is grouped and patched back to all columns. Any help much appreciated. Thanks
Nina,
Is this a question about Power Apps Error-Handling?
Hello Matthew! I have a Network error using patch:
Lina,
In the error description it says “the Title field is required”. You must ensure it is included in the form OR make title a field that is not required in the SharePoint list settings.
Hello. Great Information. I’m wondering how you would do this with multiple Patch functions. I have 3 patch functions going to three different lists. I don’t want any of the patch functions to happen if there’s a problem with one of the patches. How might this be handled?
Patti,
What you are looking for is called “rollback.” When a PATCH fails, then revert any other successful changes. Unfortunately, Power Apps does not have that. Which is kind of a pain.
One thing you can do is use the VALIDATE function to ensure the list will accept the patched records. I know, it doesn’t mitigate network issues, but it may be good enough if users are on a PC. Also, you could consider creating a flow to clean-up orphaned records that failed to patch. That’s another idea.
I don’t know your data-model. Is it possible to use only one-list? Sure, normalization is good. But maybe it would be better to denormalize here. Food for thought.
Thanks for responding. Combining into one list isn’t possible based on the current structure of the lists. You would recommend the Validate as opposed to IsError stuff? Is it possible to do the validations for all three lists before the patch functions?
Patti,
Yes, validate is possible to do before your patch functions. Just place it before the PATCH code. It sends the record to the datasource for validation but doesn’t post it. It’s a pre-insert check.
I don’t think IsError would work here. IsError will capture an error on submission. But you wanted to know if all 3 records will submit successfully so I think Validate is best. That being said, always wrap your PATCH functions in error handing such as IsError or IfError.
Thanks for the info. Will work on it.
One more quick question. The “patch” isn’t using the form fields. It’s using fields that I put on a screen to collect data and patch to the lists. Is the Validate still appropriate for that since it’s not directly in the form?
Nice !!!