Skip to content

Commit 1680e2a

Browse files
committed
Fixed Acrolinx scores
1 parent 384cb20 commit 1680e2a

File tree

3 files changed

+58
-58
lines changed

3 files changed

+58
-58
lines changed

powerapps-docs/developer/data-platform/troubleshoot-plug-in.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ contributors:
2020

2121
[!INCLUDE[cc-terminology](includes/cc-terminology.md)]
2222

23-
This topic contains information about errors that can occur due to plug-in execution and how to fix them.
23+
This article contains information about errors that can occur due to plug-in execution and how to fix them.
2424

2525
## Error: Sandbox Worker process crashed
2626

2727
Error Code: `-2147204723`<br />
2828
Error Message: `The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.`
2929

30-
This error simply means that the worker process running your plug-in code crashed. The reason it crashed may be your plug-in, but it could also be another plug-in running concurrently for your organization. Because the process crashed, we can’t extract any more specific information about why it crashed. But after examining data from the crash dumps after the fact, we have found that this usually happens for one of the 4 reasons below:
30+
This error simply means that the worker process running your plug-in code crashed. The reason it crashed may be your plug-in, but it could also be another plug-in running concurrently for your organization. Because the process crashed, we can’t extract any more specific information about why it crashed. But after examining data from the crash dumps after the fact, we have found that this usually happens for one of the four reasons below:
3131

3232
- Unhandled exception in plugin
3333
- Stack Overflow error in plug-in
@@ -38,7 +38,7 @@ This error simply means that the worker process running your plug-in code crashe
3838

3939
As mentioned in [Handle exceptions in plug-ins](handle-exceptions.md), when you write a plug-in you should try to anticipate which operations may fail and wrap them in a try-catch block. When any errors occur, you should use the <xref:Microsoft.Xrm.Sdk.InvalidPluginExecutionException> to gracefully terminate the operation with an error meaningful to the user.
4040

41-
A common scenario for this is when using a the [HttpClient.SendAsync Method](/dotnet/api/system.net.http.httpclient.sendasync?view=netframework-4.6.2&preserve-view=true) or [HttpClient.GetAsync Method](/dotnet/api/system.net.http.httpclient.getasync?view=netframework-4.6.2&preserve-view=true) which are asynchronous operations that returns a [Task](/dotnet/api/system.threading.tasks.task-1?view=netframework-4.6.2&preserve-view=true). To make this work in a plug-in where code needs to be synchronous, people may use the [Task&lt;TResult&gt;.Result Property](/dotnet/api/system.threading.tasks.task-1.result?view=netframework-4.6.2&preserve-view=true). When an error occurs, this returns an [AggregateException](/dotnet/api/system.aggregateexception?view=netframework-4.6.2&preserve-view=true) which consolidates multiple failures into a single exception which can be difficult to handle. A better design is to use [Task&lt;TResult&gt;.GetAwaiter()](/dotnet/api/system.threading.tasks.task-1.getawaiter?view=netframework-4.6.2&preserve-view=true).[GetResult()](/dotnet/api/system.runtime.compilerservices.taskawaiter-1.getresult?view=netframework-4.6.2&preserve-view=true) because it propagates the results as the specific error that caused the failure.
41+
A common scenario for this is when using the [HttpClient.SendAsync Method](/dotnet/api/system.net.http.httpclient.sendasync?view=netframework-4.6.2&preserve-view=true) or [HttpClient.GetAsync Method](/dotnet/api/system.net.http.httpclient.getasync?view=netframework-4.6.2&preserve-view=true) that are asynchronous operations that returns a [Task](/dotnet/api/system.threading.tasks.task-1?view=netframework-4.6.2&preserve-view=true). To make this work in a plug-in where code needs to be synchronous, people may use the [Task&lt;TResult&gt;.Result Property](/dotnet/api/system.threading.tasks.task-1.result?view=netframework-4.6.2&preserve-view=true). When an error occurs, this returns an [AggregateException](/dotnet/api/system.aggregateexception?view=netframework-4.6.2&preserve-view=true) which consolidates multiple failures into a single exception, which can be difficult to handle. A better design is to use [Task&lt;TResult&gt;.GetAwaiter()](/dotnet/api/system.threading.tasks.task-1.getawaiter?view=netframework-4.6.2&preserve-view=true).[GetResult()](/dotnet/api/system.runtime.compilerservices.taskawaiter-1.getresult?view=netframework-4.6.2&preserve-view=true) because it propagates the results as the specific error that caused the failure.
4242

4343
The following example shows the correct way to manage the exception and an outbound call using [HttpClient.GetAsync Method](/dotnet/api/system.net.http.httpclient.getasync?view=netframework-4.6.2&preserve-view=true). This plug-in will attempt to get the response text for a Url set in the unsecure config for a step registered for it.
4444

@@ -130,9 +130,9 @@ namespace ErrorRepro
130130

131131
### Stack Overflow error in plug-in
132132

133-
This type of error occurs most frequently right after you make some change in your plug-in code. Some people use their own set of base classes to streamline their development experience. Sometimes these errors originate from changes to those base classes which a particular plug-in depends on.
133+
This type of error occurs most frequently right after you make some change in your plug-in code. Some people use their own set of base classes to streamline their development experience. Sometimes these errors originate from changes to those base classes that a particular plug-in depends on.
134134

135-
For example, a recursive call without a termination condition, or a termination condition which doesn’t cover all scenarios can cause this to happen. More information: [StackOverflowException Class > Remarks](/dotnet/api/system.stackoverflowexception?view=netframework-4.6.2&preserve-view=true#remarks)
135+
For example, a recursive call without a termination condition, or a termination condition, which doesn’t cover all scenarios can cause this to happen. More information: [StackOverflowException Class > Remarks](/dotnet/api/system.stackoverflowexception?view=netframework-4.6.2&preserve-view=true#remarks)
136136

137137
You should review any code changes that were applied recently for the plug-in and any other code that the plug-in code depends on.
138138

@@ -244,21 +244,21 @@ Exception rethrown at [0]:
244244

245245
### Using threads to queue work with no try/catch in thread delegate
246246

247-
You shouldn’t use parallel execution patterns in plug-ins. This is called out in this best practice topic: [Do not use parallel execution within plug-ins and workflow activities](best-practices/business-logic/do-not-use-parallel-execution-in-plug-ins.md). Using these patterns can cause issues managing the transaction in a synchronous plug-in. However, another reason to not use these patterns is that any work done outside of a try/catch block in a thread delegate can crash the worker process.
247+
You shouldn’t use parallel execution patterns in plug-ins. This is called out in this best practice article: [Don't use parallel execution within plug-ins and workflow activities](best-practices/business-logic/do-not-use-parallel-execution-in-plug-ins.md). Using these patterns can cause issues managing the transaction in a synchronous plug-in. However, another reason to not use these patterns is that any work done outside of a try/catch block in a thread delegate can crash the worker process.
248248

249249
### Worker process reaches memory limit
250250

251-
Each worker process has a finite amount of memory. There are conditions where multiple concurrent operations which include large amounts of data could exceed the available memory and cause the process worker to crash.
251+
Each worker process has a finite amount of memory. There are conditions where multiple concurrent operations that include large amounts of data could exceed the available memory and cause the process worker to crash.
252252

253253
#### RetrieveMultiple with File data
254254

255-
The common scenario in this case is when a plug-in executes for a `RetrieveMultiple` operation where the request includes file data. For example, when retrieving email which include any file attachments. The amount of data that may be returned in a query like this is unpredictable because any email my be related to any number of file attachments and the attachments themselves can vary in size.
255+
The common scenario in this case is when a plug-in executes for a `RetrieveMultiple` operation where the request includes file data. For example, when retrieving email, which includes any file attachments. The amount of data that may be returned in a query like this is unpredictable because any email may be related to any number of file attachments and the attachments themselves can vary in size.
256256

257-
When multiple requests of a similar nature are running concurrently, the amount of memory required becomes quite large. If it exceeds the limit the process will crash. The key to preventing this is limiting `RetrieveMultiple` queries that include entities with related file attachments. Retrieve the records using `RetrieveMultiple`, but retrieve any related files as needed using individual `Retrieve` operations.
257+
When multiple requests of a similar nature are running concurrently, the amount of memory required becomes large. If it exceeds the limit the process will crash. The key to preventing this is limiting `RetrieveMultiple` queries that include entities with related file attachments. Retrieve the records using `RetrieveMultiple`, but retrieve any related files as needed using individual `Retrieve` operations.
258258

259259
#### Memory Leaks
260260

261-
A less common scenario is where the code in the plug-in is leaking memory. This can occur when the plug-in isn’t written as stateless, which is another best practice: [Develop IPlugin implementations as stateless](best-practices/business-logic/develop-iplugin-implementations-stateless.md). When the plug-in isn’t stateless and there is an attempt to continually add data to a stateful property like an array. The amount of data grows to the point where it uses all the available memory.
261+
A less common scenario is where the code in the plug-in is leaking memory. This can occur when the plug-in isn’t written as stateless, which is another best practice: [Develop IPlugin implementations as stateless](best-practices/business-logic/develop-iplugin-implementations-stateless.md). When the plug-in isn’t stateless and there's an attempt to continually add data to a stateful property like an array. The amount of data grows to the point where it uses all the available memory.
262262

263263
## Transaction errors
264264

@@ -273,7 +273,7 @@ Error Message: `There is no active transaction. This error is usually caused by
273273
> [!NOTE]
274274
> The top error was added most recently. It should occur immediately and in the context of the plug-in that contains the problem. The bottom error can still occur in different circumstances, typically involving custom workflow activities. It may be due to problems in another plug-in.
275275
276-
To understand the message, you need to appreciate that any time an error related to a data operation occurs within a synchronous plug-in the transaction for the entire operation will be ended.
276+
To understand the message, you need to appreciate that anytime an error related to a data operation occurs within a synchronous plug-in the transaction for the entire operation will be ended.
277277

278278
More information: [Scalable Customization Design in Microsoft Dataverse](scalable-customization-design/overview.md)
279279

@@ -294,7 +294,7 @@ Blocking is the most common cause for a SQL Timeout error is that the operation
294294

295295
Blocking may be due to other concurrent operations. Your code may work fine in isolation in a test environment and still be susceptible to conditions that will only occur when multiple users are initiating the logic in your plug-in.
296296

297-
When writing plug-ins, it is essential to understand how to design customizations that are scalable. More information: [Scalable Customization Design in Dataverse](scalable-customization-design/overview.md)
297+
When writing plug-ins, it's essential to understand how to design customizations that are scalable. More information: [Scalable Customization Design in Dataverse](scalable-customization-design/overview.md)
298298

299299
### Cascade operations
300300

@@ -326,16 +326,16 @@ Error Message: `Message size exceeded when sending context to Sandbox. Message s
326326

327327
This error occurs when a message payload is greater than 116.85 MB **AND** a plug-in is registered for the message. The error message will include the size of the payload that caused this error.
328328

329-
The limit will help ensure that users running applications cannot interfere with each other based on resource constraints. The limit will help provide a level of protection from unusually large message payloads that threaten the availability and performance characteristics of the Dataverse platform.
329+
The limit will help ensure that users running applications can't interfere with each other based on resource constraints. The limit will help provide a level of protection from unusually large message payloads that threaten the availability and performance characteristics of the Dataverse platform.
330330

331-
116.85 MB is large enough that it should be rare to encounter this case. The most likely situation where this case might occur is when you retrieve a record with multiple related records which include large binary files.
331+
116.85 MB is large enough that it should be rare to encounter this case. The most likely situation where this case might occur is when you retrieve a record with multiple related records that include large binary files.
332332

333-
If you encounter this error you can:
333+
If you encounter this error, you can:
334334

335335
1. Remove the plug-in for the message. If there are no plug-ins registered for the message, the operation will complete without an error.
336336
2. If the error is occurring in a custom client, you can modify your code so that it doesn't attempt to perform the work in a single operation. Instead, write code to retrieve the data in smaller parts.
337337

338-
## Error: The given key was not present in the dictionary
338+
## Error: The given key wasn't present in the dictionary
339339

340340
Dataverse frequently uses classes derived from the abstract <xref:Microsoft.Xrm.Sdk.DataCollection`2> class that represents a collection of keys and values. For example, with plug-ins the <xref:Microsoft.Xrm.Sdk.IExecutionContext>.<xref:Microsoft.Xrm.Sdk.IExecutionContext.InputParameters> property is a <xref:Microsoft.Xrm.Sdk.ParameterCollection> derived from the <xref:Microsoft.Xrm.Sdk.DataCollection`2> class. These classes are essentially dictionary objects where you access a specific value using the key name.
341341

@@ -348,7 +348,7 @@ If the developer caught the exception and returned an <xref:Microsoft.Xrm.Sdk.In
348348
Error Code: `-2147220891`<br />
349349
Error Message: `ISV code aborted the operation.`
350350

351-
However, with this error it is common that the developer doesn't catch it properly and the following error will be returned:
351+
However, with this error it's common that the developer doesn't catch it properly and the following error will be returned:
352352

353353
Error Code: `-2147220956`<br />
354354
Error Message: `An unexpected error occurred from ISV code.`
@@ -360,11 +360,11 @@ Error Message: `An unexpected error occurred from ISV code.`
360360

361361
This error frequently occurs at design time and can be due to a misspelling or using the incorrect casing. The key values are case sensitive.
362362

363-
At run-time the error is frequently due to the developer assuming that the value will be present when it isn't. For example, in a plug-in that is registered for the update of a table, only those values which are changed will be included in the <xref:Microsoft.Xrm.Sdk.Entity>.<xref:Microsoft.Xrm.Sdk.Entity.Attributes> collection.
363+
At run-time the error is frequently due to the developer assuming that the value will be present when it isn't. For example, in a plug-in that is registered for the update of a table, only those values that are changed will be included in the <xref:Microsoft.Xrm.Sdk.Entity>.<xref:Microsoft.Xrm.Sdk.Entity.Attributes> collection.
364364

365365
### Prevention
366366

367-
To prevent this error you must check that the key exists before attempting to use it to access a value.
367+
To prevent this error, you must check that the key exists before attempting to use it to access a value.
368368

369369
For example, when accessing a table column, you can use the <xref:Microsoft.Xrm.Sdk.Entity>.<xref:Microsoft.Xrm.Sdk.Entity.Contains(System.String)> method to check whether a column exists in a table as shown in the following code.
370370

0 commit comments

Comments
 (0)