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
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.
24
24
25
25
## Error: Sandbox Worker process crashed
26
26
27
27
Error Code: `-2147204723`<br />
28
28
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.`
29
29
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:
31
31
32
32
- Unhandled exception in plugin
33
33
- Stack Overflow error in plug-in
@@ -38,7 +38,7 @@ This error simply means that the worker process running your plug-in code crashe
38
38
39
39
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.
40
40
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<TResult>.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<TResult>.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<TResult>.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<TResult>.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.
42
42
43
43
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.
44
44
@@ -130,9 +130,9 @@ namespace ErrorRepro
130
130
131
131
### Stack Overflow error in plug-in
132
132
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.
134
134
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)
136
136
137
137
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.
138
138
@@ -244,21 +244,21 @@ Exception rethrown at [0]:
244
244
245
245
### Using threads to queue work with no try/catch in thread delegate
246
246
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.
248
248
249
249
### Worker process reaches memory limit
250
250
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.
252
252
253
253
#### RetrieveMultiple with File data
254
254
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.
256
256
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.
258
258
259
259
#### Memory Leaks
260
260
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.
262
262
263
263
## Transaction errors
264
264
@@ -273,7 +273,7 @@ Error Message: `There is no active transaction. This error is usually caused by
273
273
> [!NOTE]
274
274
> 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.
275
275
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.
277
277
278
278
More information: [Scalable Customization Design in Microsoft Dataverse](scalable-customization-design/overview.md)
279
279
@@ -294,7 +294,7 @@ Blocking is the most common cause for a SQL Timeout error is that the operation
294
294
295
295
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.
296
296
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)
298
298
299
299
### Cascade operations
300
300
@@ -326,16 +326,16 @@ Error Message: `Message size exceeded when sending context to Sandbox. Message s
326
326
327
327
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.
328
328
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.
330
330
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.
332
332
333
-
If you encounter this error you can:
333
+
If you encounter this error, you can:
334
334
335
335
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.
336
336
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.
337
337
338
-
## Error: The given key was not present in the dictionary
338
+
## Error: The given key wasn't present in the dictionary
339
339
340
340
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.
341
341
@@ -348,7 +348,7 @@ If the developer caught the exception and returned an <xref:Microsoft.Xrm.Sdk.In
348
348
Error Code: `-2147220891`<br />
349
349
Error Message: `ISV code aborted the operation.`
350
350
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:
352
352
353
353
Error Code: `-2147220956`<br />
354
354
Error Message: `An unexpected error occurred from ISV code.`
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.
362
362
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.
364
364
365
365
### Prevention
366
366
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.
368
368
369
369
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.
0 commit comments