title: CRM Plugin: Custom Exception in Sandbox
body: <p>I have a Dynamics CRM 2013 plugin executing in the Sandbox.</p>
  
  <p>This code has the following custom exception class:</p>
  
  <pre><code>    [Serializable]
      public class PluginValidationException : Exception
      {
          public PluginValidationException()
          {
          }
  
          protected PluginValidationException(SerializationInfo info, StreamingContext context) 
              : base(info, context)
          {            
          }
  
          public PluginValidationException(string message)
              : base(message)
          {
          }
  
          public PluginValidationException(string message, Exception inner)
              : base(message, inner)
          {
          }
      }
  </code></pre>
  
  <p>When this exception is thrown in the plugin it results in a generic error window, with no details in the log file:</p>
  
  <p><img src="https://i.stack.imgur.com/9kfrc.png" alt="enter image description here"></p>
  
  <p><em>Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: System.Runtime.Serialization.SerializationException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #1355B4E4Detail: 
  
    -2147220970
    
      
        CallStack
           at Microsoft.Crm.Application.Platform.ServiceCommands.PlatformCommand.XrmExecuteInternal()
     at Microsoft.Crm.Application.Platform.ServiceCommands.CreateCommand.Execute()
     at Microsoft.Crm.Application.Platform.EntityProxy.Create(Boolean performDuplicateCheck, Guid auditingTransactionId)
     at Microsoft.Crm.Application.Platform.EntityProxy.Create(Boolean performDuplicateCheck)
     at Microsoft.Crm.Application.Platform.EntityProxy.CreateAndRetrieve(String[] columnSet, Boolean performDuplicateCheck)
     at Microsoft.Crm.Application.WebServices.InlineEdit.CommandBase.UpdateEntity(Entity entity, Boolean retrieve)
     at Microsoft.Crm.Application.WebServices.InlineEdit.SaveCommand.ExecuteCommand(String commandXml)
     at Microsoft.Crm.Application.WebServices.InlineEdit.CommandBase.Execute(String commandXml)
      
    
    System.Runtime.Serialization.SerializationException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #1355B4E4
    2014-04-06T02:04:30.0972001Z
    
    
  [Demo.DemoPlugin: Demo.DemoPlugin.BasicCrmPlugin]
  [d86b89ab-f1bc-e311-9408-000c29254b18: Demo.DemoPlugin.BasicCrmPlugin: Create of contact]
  
  </em></p>
  
  <p>Looking at the CRM trace log shows the following:</p>
  
  <p><em>System.Runtime.Serialization.SerializationException: Type 'Demo.Helpers.PluginValidationException' in assembly 'Demo.DemoPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fbb51ba1e588d276' is not marked as serializable.
             at Microsoft.Crm.Sandbox.SandboxAppDomainHelper.Execute(IServiceEndpointNotificationService serviceBusService, IOrganizationServiceFactory organizationServiceFactory, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, IPluginExecutionContext requestContext)
             at Microsoft.Crm.Sandbox.SandboxWorker.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, SandboxRequestCounter&amp; workerCounter)</em></p>
  
  <p>I do not, based on some reading, believe this is a bug - rather it is because custom <code>Exception</code> classes are not, inherently trusted as of .NET 4 (I'm using .NET 4.5.)</p>
  
  <p>Does anyone know how to make a custom exception class that will work with the CRM Sandbox. I'm using a custom exception class because I catch errors and need to distinguish between an <code>InvalidPluginExecutionException</code> an exception caused because the plug-in is incorrectly registered.</p>
  
  <p><strong>UPDATED Apr 08 2014</strong></p>
  
  <p>Here is the code in the plugin that catches the exceptions, with significant simplification for putting it on Stackoverflow:</p>
  
  <pre><code>        try
          {
              //TODO: Prevalidation Logic
              ValidatePluginExecution(crmContext, logging, out keyName);
              //TODO: Postvalidation Logic
          }
          catch (PluginValidationException ex)
          {
              //TODO: Specific logging for Plugin Validation Exception
              throw new InvalidPluginExecutionException("Did Not Validate");                    
          }
          catch (InvalidPluginExecutionException ex)
          {
              logging.Write("InvalidPluginExectionException at Plugin Validation");                    
              throw;
          }
          catch (Exception ex)
          {
              logging.Write("Unhandled Exeception During Plugin Validation Operation");
              logging.Write(ex);
              throw new InvalidPluginExecutionException("Error.  Download Log and submit to the Help Desk.", ex);                    
          }
  </code></pre>