Dataverse プラグインのトラブルシューティング
この記事では、プラグインの実行中に発生する可能性があるエラー、またはプラグインに関連する Dataverse エラー、およびそれらを回避または修正する方法について説明します。
エラー "時間変換を完了できませんでした"
エラー コード: -2147220956
エラー メッセージ: 指定された DataTime に Kind プロパティが正しく設定されていないため、変換を完了できませんでした。 たとえば、Kind プロパティが DateTimeKind.Local の場合、ソースタイム ゾーンは TimeZoneInfo.Local である必要があります。
このエラーは、プラグイン コードの TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) 呼び出し中に、サンティアゴまたは Volgograd タイム ゾーンの DateTime
値を世界協定時刻 (UTC) に変換する際に発生する可能性があります。
このエラーは既知の製品の制限に起因し、現在のところ回避策はありません。
詳細については、「 ユーザーのタイム ゾーン設定を指定するを参照してください。
エラー "サンドボックス ワーカー プロセスがクラッシュしました"
エラー コード: -2147204723
エラー メッセージ: サンドボックス ワーカー プロセスがクラッシュしたため、プラグインの実行に失敗しました。 これは通常、プラグイン コードのエラーが原因です。
このエラーは、プラグイン コードを実行しているワーカー プロセスがクラッシュしたことを意味します。 プラグインがクラッシュの原因である可能性がありますが、組織で同時に実行されている別のプラグインである可能性もあります。 プロセスがクラッシュしたため、クラッシュした理由に関するより具体的な情報を抽出することはできません。 しかし、その後クラッシュ ダンプからのデータを調べた結果、このエラーは通常、次の 4 つの理由のいずれかが原因で発生することがわかりました。
- プラグインのハンドルされない例外
- スレッドを使用してスレッド デリゲートで try/catch なしで処理をキューに格納する
- プラグインのスタック オーバーフロー エラー
- ワーカー プロセスがメモリ制限に達しました
プラグインのハンドルされない例外
プラグインを記述するときは、失敗する可能性のある操作を予測し、try-catch ブロックにラップする必要があります。 エラーが発生した場合は、 InvalidPluginExecutionException クラスを使用して、ユーザーにとって意味のあるエラーで操作を正常に終了する必要があります。
詳細については、「 プラグインでの例外のハンドル」を参照してください。
この例外の一般的なシナリオは、 HttpClient.SendAsync または HttpClient.GetAsync メソッドを使用する場合です。 これらの HttpClient メソッドは、 Task を返す非同期操作です。 コードを同期する必要があるプラグインで作業するには、 Task<TResult> を使用できます。Result プロパティ。 エラーが発生すると、 Result
は AggregateException を返します。 AggregateException
では、複数のエラーが 1 つの例外に統合されるため、処理が困難な場合があります。 より優れた方法として、Task<TResult>.GetAwaiter().GetResult() を使用できます。これは、失敗の原因となった特定のエラーとして結果を反映します。
次の例は、 HttpClient.GetAsync メソッドを使用して例外と送信呼び出しを管理する正しい方法を示しています。 このプラグインは、登録されたステップのセキュリティで保護されていない構成で設定された URI の応答テキストを取得しようとします。
using Microsoft.Xrm.Sdk;
using System;
using System.Net.Http;
namespace ErrorRepro
{
public class AsyncError : IPlugin
{
private readonly string webAddress;
public AsyncError(string unsecureConfig)
{
if (string.IsNullOrEmpty(unsecureConfig)) {
throw new InvalidPluginExecutionException("The ErrorRepro.AsyncError plug-in requires that a Url be set in the unsecure configuration for the step registration.");
}
webAddress = unsecureConfig;
}
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace($"Starting ErrorRepro.AsyncError");
tracingService.Trace($"Sending web request to {webAddress}");
try
{
string responseText = GetWebResponse(webAddress, tracingService);
tracingService.Trace($"Result: {responseText.Substring(0, 100)}");
}
catch (Exception ex)
{
tracingService.Trace($"Error: ErrorRepro.AsyncError {ex.Message}");
throw new InvalidPluginExecutionException(ex.Message);
}
tracingService.Trace($"Ending ErrorRepro.AsyncError");
}
//Gets the text response of an outbound web service call
public string GetWebResponse(string webAddress, ITracingService tracingService)
{
try
{
using (HttpClient client = new HttpClient())
{
client.Timeout = TimeSpan.FromMilliseconds(15000); //15 seconds
client.DefaultRequestHeaders.ConnectionClose = true; //Set KeepAlive to false
HttpResponseMessage response = client.GetAsync(webAddress).GetAwaiter().GetResult(); //Make sure it is synchronous
response.EnsureSuccessStatusCode();
tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse succeeded.");
string responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); //Make sure it is synchronous
tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse responseContent parsed successfully.");
return responseContent;
}
}
catch (Exception ex)
{
//Capture the inner exception message if it exists.
// It should have a more specific detail.
string innerExceptionMessage = string.Empty;
if (ex.InnerException != null) {
innerExceptionMessage = ex.InnerException.Message;
}
tracingService.Trace($"Error in ErrorRepro.AsyncError : {ex.Message} InnerException: {innerExceptionMessage}");
if (!string.IsNullOrEmpty(innerExceptionMessage))
{
throw new Exception($"A call to an external web service failed. {innerExceptionMessage}", ex);
}
throw new Exception("A call to an external web service failed.", ex);
}
}
}
}
スレッドを使用して、スレッド代理人で try/catch を使用せずに作業をキューに入れます
プラグインでは並列実行パターンを使用しないでください。このアンチパターンは、ベスト プラクティスの記事「 プラグインとワークフロー アクティビティ内で並列実行を使用しない」で説明されています。 これらのパターンを使用すると、同期プラグインでのトランザクションの管理で問題が発生する可能性があります。 ただし、これらのパターンを使用しないもう 1 つの理由は、スレッド デリゲート内の try
/catch
ブロックの外部で行われた作業がワーカー プロセスをクラッシュさせる可能性があるということです。
重要
ワーカー プロセスがクラッシュすると、そのプロセスで現在実行中のプラグインとその他のプラグインの実行が終了します。 これには、所有または保守していないプラグインが含まれます。
Application Insights による救助
以前は、クラッシュしたワーカー プロセスからハンドルされないプラグイン例外のスタック トレースまたはその他の実行情報を取得することは不可能でした。 ただし、Dataverse では、Application Insights への実行エラーのログ記録がサポートされるようになりました。 この関数を有効にするには、プラグインが登録されている環境に Application Insights をリンクできます。 リンクされると、プラグインのクラッシュのログが自動的に発生します。
詳細については、「 Export data to Application Insights」を参照してください。
Application Insights 環境がリンクされると、作業プロセスのクラッシュに関する次のデータを使用して問題のトラブルシューティングを行うことができます。
Application Insights でクラッシュ レポートに移動するには、次の手順に従います。
- Application Insights を環境にリンク。
- プラグイン例外によってワーカー プロセスのクラッシュ エラーが発生するまで待ちます。
- Power Platform 管理センターで Application Insights に移動します。
- Application Insights ページで、左側のパネルで Failures を選択します。
- Failures ページで、Exceptions を選択します。
- Exception の問題 IDのOverallの一覧で、 microsoft.PowerPlatform.Dataverse.Plugin.PluginWorkerCrashException を選択します。
- ページの右側にある Overall で、 PluginWorkerCrashException を選択します。 記録されたすべてのワーカー プロセスクラッシュ例外の詳細が表示されます。
- 左側のパネルで目的の例外を検索して選択すると、例外の詳細レポートがページの右側に表示されます (例については、前のスクリーンショットを参照してください)。
- スタック トレースにアクセスするには、レポートで CrashDetails を展開します。
プラグインのスタック オーバーフロー エラー
この種のエラーは、プラグイン コードに変更を加えた直後に最も頻繁に発生します。 一部の人々は、独自の基本クラスのセットを使用して、開発エクスペリエンスを合理化します。 これらのエラーは、特定のプラグインが依存する基本クラスへの変更に起因する場合があります。
たとえば、終了条件のない再帰呼び出しや、すべてのシナリオに対応していない終了条件は、このエラーを発生させる可能性があります。 詳細については、「 StackOverflowException クラス > 解説を参照してください。
プラグインに最近適用されたコードの変更、およびプラグイン コードが依存するその他のコードをレビューする必要があります。
例
次のプラグイン コードでは、制限のない再帰呼び出しにより StackOverflowException
が発生します。 トレースを使用してエラーをキャプチャしようとしても、トレースとエラーは返されません。これは、処理するワーカー プロセスが終了したためです。
using Microsoft.Xrm.Sdk;
using System;
namespace ErrorRepro
{
public class SOError : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace($"Starting ErrorRepro.SOError");
try
{
tracingService.Trace($"Calling RecursiveMethodWithNoLimit to trigger StackOverflow error.");
RecursiveMethodWithNoLimit(tracingService); //StackOverflowException occurs here.
}
catch (Exception ex)
{
//This trace will not be written
tracingService.Trace($"Error in ErrorRepro.SOError {ex.Message}");
//This error will never be thrown
throw new InvalidPluginExecutionException($"Error in ErrorRepro.SOError. {ex.Message}");
}
//This trace will never be written
tracingService.Trace($"Ending ErrorRepro.SOError");
}
public static void RecursiveMethodWithNoLimit(ITracingService tracingService)
{
tracingService.Trace($"Starting ErrorRepro.SOError.RecursiveMethodWithNoLimit");
RecursiveMethodWithNoLimit(tracingService);
tracingService.Trace($"Ending ErrorRepro.SOError.RecursiveMethodWithNoLimit");
}
}
}
同期プラグインの手順では、前に示したプラグイン コードは、要求がエラーのある追加の詳細を含む 構成されている場合に、Web API で次のエラーを返します。
{
"error": {
"code": "0x8004418d",
"message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey": "Plugin/ErrorRepro.SOError, ErrorRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c2bee3e550ec0851",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey": "d5958631-b87e-eb11-a812-000d3a4f50a7",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey": "1",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey": "a3028bda-73c2-4eef-bcb5-157c5a4c323e",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey": "Active",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey": "Active",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory": "SystemFailure",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName": "SandboxWorkerNotAvailable",
"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode": "500",
"@Microsoft.PowerApps.CDS.HelpLink": "http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a8004418d&client=platform",
"@Microsoft.PowerApps.CDS.TraceText": "\r\n[ErrorRepro: ErrorRepro.SOError]\r\n[d5958631-b87e-eb11-a812-000d3a4f50a7: ErrorRepro.SOError: Create of account]\r\n\r\n",
"@Microsoft.PowerApps.CDS.InnerError.Message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A"
}
}
このエラーがプラグイン Tracelog にどのように記録されるかを次に示します。
Unhandled exception:
Exception type: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]
Message: The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ActivityId>48c5818e-4912-42f0-b1b6-e3bbe7ae013d</ActivityId>
<ErrorCode>-2147204723</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<HelpLink i:nil="true" />
<Message>The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433</Message>
<Timestamp>2021-03-06T22:14:22.0629638Z</Timestamp>
<ExceptionRetriable>false</ExceptionRetriable>
<ExceptionSource>WorkerCommunication</ExceptionSource>
<InnerFault i:nil="true" />
<OriginalException>System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay)</OriginalException>
<TraceText i:nil="true" />
</OrganizationServiceFault>
ワーカー プロセスがメモリ制限に達しました
各ワーカー プロセスのメモリは有限です。 大量のデータを含む複数の同時操作が使用可能なメモリを超え、プロセス ワーカーがクラッシュする可能性がある状況があります。
ファイル データが含まれる RetrieveMultiple
この場合の一般的なシナリオは、要求にファイル データが含まれる RetrieveMultiple
操作に対してプラグインを実行する場合です。 たとえば、添付ファイルを含む電子メールを取得する場合などです。 このようなクエリで返される可能性のあるデータの量は、電子メールが任意の数の添付ファイルに関連付けられている可能性があり、添付ファイルのサイズが異なる可能性があるため、予測できません。
同様の性質の複数のリクエストが同時に実行されている場合、必要なメモリの量が非常に大きくなります。 メモリの量が上限を超えると、プロセスがクラッシュします。 この状況を防ぐ鍵となるのは、関連する添付ファイルを含むエンティティを含む RetrieveMultiple
クエリを制限することです。 RetrieveMultiple
を使用してレコードを取得しますが、ただし、個別の Retrieve
操作を使って、必要に応じて関連ファイルを取得します。
メモリ リーク
あまり一般的ではないシナリオは、プラグインのコードのメモリがリークしている場合です。 この状況は、プラグインがステートレスとして書き込まれていない場合に発生する可能性があります。これはもう 1 つのベスト プラクティスです。 詳細については、「 Develop プラグインの実装をステートレスとしてする」を参照してください。 プラグインがステートレスではなく、配列などのステートフル プロパティにデータを継続的に追加しようとすると、使用可能なすべてのメモリを使用する時点までデータ量が増加します。
トランザクション エラー
トランザクションに関連する 2 種類の一般的なエラーがあります。
エラー コード: -2146893812
エラー メッセージ: ISV コードにより、開いているトランザクション数が減少しました。 カスタム プラグインでは、OrganizationService 呼び出しからの例外をキャッチして処理を続行しないでください。
エラー コード: -2147220911
エラー メッセージ: アクティブなトランザクションがありません。 通常、このエラーは、サービス呼び出しからのエラーを無視し、処理を続行するカスタム プラグインによって発生します。
Note
上位エラーが最近追加されました。 これは、問題を含むプラグイン内のコンテキスト内ですぐに発生します。 下位エラーは、引き続きさまざまな状況で発生する可能性があります (通常はユーザー定義ワークフロー活動が関係する状況)。 別のプラグインの問題が原因である可能性があります。
同期プラグイン内でデータ操作に関連するエラーが発生すると、操作全体のトランザクションは終了します。
詳細については、「 Microsoft Dataverse のスケール可能なカスタマイズ設計」を参照してください。
一般的な原因は、開発者は、成功する操作を実行しようと試みることができると考えているので、その操作をtry
/catch
ブロックでラップし、失敗したときにエラーを飲み込もうとすることです。
このパターンはクライアント アプリケーションで機能する可能性があります。プラグインの実行中にデータ操作エラーが発生すると、トランザクション全体がロールバックされます。 エラーを吸収できないので、必ず InvalidPluginExecutionException を返す必要があります。
エラー "Sql error: Execution Timeout Expired" (Sql エラー: 実行タイムアウトの有効期限が切れています)
エラー コード: -2147204783
エラー メッセージ: Sql エラー: '実行タイムアウトの有効期限が切れています。 操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。'
原因
SQL タイムアウト エラーが発生する理由はさまざまです。 そのうちの 3 つを次に示します。
ブロック
SQL タイムアウト エラーの最も一般的な原因は、操作が別の SQL トランザクションによってブロックされたリソースを待機していることです。 このエラーは、Dataverse がデータの整合性を保護し、ユーザーのパフォーマンスに影響を与える実行時間の長い要求から保護した結果です。
ブロックは、他の同時実行操作が原因である可能性があります。 コードはテスト環境で分離して正常に動作する可能性があり、複数のユーザーがプラグインでロジックを開始している場合にのみ発生する条件の影響を受けやすくなります。
プラグインを書くときは、スケーラブルなカスタマイズの設計方法を理解することが重要です。 詳細については、「 Dataverse のスケール可能なカスタマイズ 設計」を参照してください。
カスケード操作
レコードの割り当てや削除などプラグインで行う特定の操作が、関連レコードのカスケード操作を開始することがあります。 これらのアクションにより、関連レコードにロックが適用され、後続のデータ操作がブロックされ、SQL タイムアウトが発生する可能性があります。
プラグインのデータ操作でこれらのカスケード操作の影響を考慮する必要があります。 詳細については、「 テーブルリレーションシップの動作」を参照してください。
これらの動作は環境によって異なる方法で構成できるため、環境が同じ方法で構成されていない限り、動作の再現が困難な場合があります。
新しいテーブルのインデックス
最近作成されたテーブルまたは列を使用してプラグインが操作を実行している場合、インデックスを管理するいくつかの Azure SQL 機能は、数日後に違いを生む可能性があります。
ユーザー特権によるエラー
クライアント アプリケーションでは、ユーザーが実行できないコマンドを無効にすることができます。 プラグイン内では、この機能はありません。 コードには、呼び出し元ユーザーに実行する権限がないオートメーションが含まれている場合があります。
ユーザーに ユーザーのコンテキストで実行 値を設定することで、正しい特権を確かに持っているユーザーのコンテキストで実行するようプラグインを登録できます。 または、別のユーザーを偽装して操作を実行することもできます。 詳細については、以下を参照してください:
無効なユーザーのコンテキストで実行中のエラー
プラグインが無効なユーザーのコンテキストで実行されると、次のエラーが返されます。
エラー メッセージ: System.ServiceModel.FaultException'1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: OrganizationContext=<Context> で SystemUserId=<User-ID> を持つユーザーが無効になっています。 無効なユーザーはシステムにアクセスできません。 このユーザーを有効にすることを検討してください。 また、ユーザーにライセンスが割り当てられない場合、ユーザーは無効になります。
このエラーをトラブルシューティングするには、クエリを実行して、無効なユーザーに登録されている手順と、関連するプラグインと SdkMessage
の詳細を見つけることができます。
https://<env-url>/api/data/v9.2/sdkmessageprocessingsteps
?$filter=_impersonatinguserid_value eq '<disabled-userId-from-error>'&
$expand=plugintypeid($select=name,friendlyname,assemblyname;
$expand=pluginassemblyid($select=solutionid,name,isolationmode)),sdkmessageid($select=solutionid,name)&
$select=solutionid,name,stage,_impersonatinguserid_value,mode
"サンドボックスにコンテキストを送信するときにメッセージ サイズを超えました" というエラー
エラー コード: -2147220970
エラー メッセージ: サンドボックスにコンテキストを送信するときにメッセージサイズを超えました。 メッセージ サイズ: ### Mb
このエラーは、メッセージ ペイロードが 116.85 MB を超え、メッセージにプラグインが登録されている場合に発生します。 エラー メッセージには、このエラーの原因となったペイロードのサイズが含まれています。
この制限は、アプリケーションを実行しているユーザーがリソースの制約に基づいて相互に干渉できないようにするのに役立ちます。 この制限は、Dataverse プラットフォームの可用性とパフォーマンスの特性を脅かす、異常に大きなメッセージ ペイロードからの保護レベルを提供するのに役立ちます。
116.85 MB は、このサポート案件では極端に大きなサイズといえます。 この案件が発生する可能性が高い状況は、大規模なバイナリ ファイルを含む複数の関連するレコードを持つレコードを回収するときです。
このエラーが発生した場合は、次のことができます。
- Message に対するプラグインを削除します。 メッセージに登録されているプラグインがない場合、操作はエラーなしで完了します。
- カスタム クライアントでエラーが発生した場合、1 つの操作で作業を行うことがないようにコードを変更できます。 その代わり、より小さいパーツのデータを回復するためのコードを記述します。
エラー "指定されたキーがディクショナリに存在していませんでした"
Dataverse では、多くの場合、キーおよび値のコレクションを表す抽象 DataCollection<TKey,TValue> クラスから派生したクラスが使用されます。 たとえば、プラグインでは、IExecutionContext.InputParameters プロパティは、DataCollection<TKey,TValue> クラスから派生したParameterCollectionです。 これらのクラスは基本的に、キー名を使用して特定の値にアクセスするディクショナリ オブジェクトです。
エラー コード
このエラーは、コード内のキー値がコレクションに存在しない場合に発生します。 結果は、プラットフォーム エラーではなく実行時エラーになります。 プラグイン内でこのエラーが発生した場合、エラー コードはエラーがキャッチされたかどうかによって異なります。
開発者が例外をキャッチし、プラグインで例外ハンドルで説明されているようにInvalidPluginExecutionExceptionを返した場合、次のエラーが返されます。
エラー コード: -2147220891
エラー メッセージ: ISV コードが操作を中止しました。
ただし、このエラーでは、開発者がそれを正しくキャッチせず、次のエラーが返されるのが一般的です。
エラー コード: -2147220956
エラー メッセージ: ISV コードから予期しないエラーが発生しました。
Note
「ISV」は独立系ソフトウェア ベンダーを意味します。
原因
このエラーは、設計時によく発生し、つづりの間違いまたは正しくないケーシングの使用が原因です。 キー値では大文字と小文字が区別されます。
実行時にエラーが発生するのは、値が存在しない場合に値が存在すると仮定した開発者が原因です。 たとえば、テーブルの更新に登録されているプラグインでは、変更された値のみが Entity.Attributes コレクションに含まれます。
解決方法
このエラーを解決するには、キーを使用して値にアクセスする前に、キーが存在することを確認する必要があります。
たとえば、テーブル列にアクセスするときは、次のコードに示すように、 Entity.Contains(String) メソッドを使用して、テーブルに列が存在するかどうかを確認できます。
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
//Check whether the name attribute exists.
if(entity.Contains("name"))
{
string name = entity["name"];
}
一部の開発者は、テーブル列にアクセスするときにこのエラーを回避するために Entity.GetAttributeValue<T>(String) メソッドを使用します。 列が存在しない場合、このメソッドは型の既定値を返します。 既定値が null の場合、このメソッドは想定どおりに動作します。 ただし、既定値が null ( DateTime
など) を返さない場合、返される値は null ではなく 1/1/0001 00:00
されます。
エラー "現在のトランザクションで既に設定されているのとは異なる分離レベルのトランザクションを開始できません"
エラー コード: -2147220989
エラー メッセージ: 現在のトランザクションで既に設定されている分離レベルとは異なるトランザクションを開始することはできません
プラグインは、ビジネス ロジックをサポートすることを目的としています。 同期プラグイン内のデータ スキーマの一部の変更はサポートされていません。 これらの操作には時間がかかる場合が多く、アプリケーションで使用されるキャッシュされたメタデータが同期しなくなる可能性があります。ただし、これらの操作は、非同期的に実行するために登録されたプラグイン ステップで実行できます。
既知の問題: Activity.RegardingObjectId 名の値がプラグインで設定されていない
この問題の最も一般的な現象は、アクティビティ レコードの Regarding フィールドに、プライマリ名の属性値ではなく (No Name)
が表示されていることです。
プラグイン内では、 EntityReference 値を使用してルックアップ属性を設定できます。 EntityReference.Name プロパティは必要ありません。 通常、ルックアップ属性値を設定するときに含める必要はありません。これは、Dataverse によって設定されるためです。 イベント パイプラインの PreOperation ステージで、このような値を設定する必要があります。 詳細については、「 Event 実行パイプライン」を参照してください。
このルールの例外は、 ActivityPointer.RegardingObjectId 参照を設定する場合です。 ActivityPointer
から派生したすべてのエンティティ型は、この参照を継承します。 既定では、 Appointment、 Chat、 Email、 Fax、 Letter、 PhoneCall、 RecurringAppointmentMaster、アクティビティの種類として作成されたすべてのカスタム テーブルが含まれます。 詳細については、「 Activity テーブル」を参照してください。
PreOperation ステージでこの値を設定した場合、名前の値は Dataverse によって追加されません。 値は null で、この値を含める必要がある書式設定された値は、レコードを取得するときに存在しません。
回避策
この問題を回避するには、次の 2 つの方法があります。
- ルックアップ属性の値を設定する前に、 EntityReference.Name プロパティ値を正しいプライマリ名フィールド値で設定できます。
- 参照値は、PreOperation ステージではなく、PreValidation ステージで設定できます。