Logging and Handling Microsoft Dynamics CRM 2013 Exceptions – Part 3

In the previous post I described a solution to the business problem of logging & handling implementation level exceptions (presented in the first post of this series).
In this post, I will supply an actual solution, demonstrate common usage scenarios and other solution features.

Before I walkthrough usage scenarios, some implementation notes:

In order to support exceptions raised from transactional components (such as Plugin registered to pre/post operation stages), the LogException method in ExceptionManagement.cs file is using the ExecuteMultipleRequest class to execute the e4d_LogExceptionRequest request. As the ExecuteMultipleRequest instance is external to the Plugin transaction, it manages to create the Exception record without the Plugin transaction rolling it back. Using the Execute method directly with the e4d_LogExceptionRequest request instead, would have executed the LogException Action, but the created Exception record would have been deleted by the Plugin transaction rollback, leaving no trace.

The provided Exception Management solution is unmanaged. This allows you to modify the solution freely but note that unmanaged solution can not be uninstalled.

The provided Exception Management solution is exported as MSCRM2013 6.0 compatible.

As an Exception record is created on behalf of a user, all users must have the Create, Read and Write privileges for the Exception entity.
The solution contains a custom Security Role named Exception Logging Authorized which includes these privileges for the Exception entity. Make sure you add this role to your users or add the privilege to their existing roles.

Ok, let’s get some work done:

Step 1: import and configure the Exception Management solution:

1. Download and extract the E4D MSCRM2013 Excreption Management.zip package.
2. Import the solution ExceptionManagement_1_0_0_0_target_CRM_6.0.zip.  Leave the ‘Enable any SDK message…’ checkbox checked.
3. Add the Exception entity to the Settings area.
4. Publish the solution.
5. Add the Exception Logging Authorized Security Role to all users.

Step 2: Follow the relevant scenario below to use the Exception Management functionality from your custom code:

Scenario 1: Logging Exceptions from JavaScript code running in Entity form

1. Open the target entity Form Properties window.
2. In the Events tab, under Form Libraries, add the ExceptionManagement.js library to the form libraries.
3. If the JavaScript Web Resource that contains your custom code does not appear in the form libraries, add it. Make sure it appears below the e4d_ExceptionManagement.js library.

image_thumb5_thumb

4. In your custom JavaScript code (someFunction in my example), wrap the target code with Try-Catch blocks.
5. In the Catch block, add the following line of code. You can add your own error handling code in the Catch block.

Sdk.logException(error, Sdk.e4d_LogExceptionRequest.PriorityLevel.LOW);

Your code should look similar to this:

function someFunction()
{
try
{
//your custom business logic here
}
catch(error)
{
//your custom exception handling here
//log exception. This is the only line of code required in your custom code
//You can set the Priority level to MEDIUM, HIGH or CRITICAL instead of LOW
Sdk.logException(error, Sdk.e4d_LogExceptionRequest.PriorityLevel.LOW);
}
}

6. Save and publish the entity form.

Scenario 2: Logging Exceptions from JavaScript code running in HTML Web Resource

1. In your HTML Web Resource, add the following references in that order:

    <script src=”ClientGlobalContext.js.aspx” type=”text/javascript”></script>
<script src=”e4d_exceptionManagement.js” type=”text/javascript”></script>

2. Follow steps 4,5 in the Scenario 1. 3.
3. Save and publish the Web Resource

Scenario 3: Logging Exceptions from c# code running in Plugin/Custom Workflow Activity/.net application

1. Add the ExceptionManagement.cs file to your Visual Studio project
2. In your code, add the following using statement

   using ExceptionMgmtServices;

3. wrap the target code with Try-Catch blocks
4. In the Catch block, add the following line of code. You can add your own error handling code in the Catch block

string friendlyMessage = ExceptionManagement.LogException(ex, service, PriorityLevel.LOW);

Your code should look something like this:

try
{
//your custom business logic here
}
catch (Exception ex)
{
//your custom exception handling here
//You can set the Priority level to MEDIUM, HIGH, CRITICAL instead of LOW
string friendlyMessage = ExceptionManagement.LogException(ex, service, PriorityLevel.LOW);
//Optionally, throw out the exception to return friendly message to the client
throw new Exception(friendlyMessage);
}

I advise you test the relevant scenarios by generating an intentional exception, such as calling a non-existing function. Make sure an error message is displayed, an Exception record is created and that the Exception details are correct.

The ExceptionManagement_1_0_0_0_target_CRM_6.0.zip contains a Web Resource named ClientSideExceptionDemo.htm which demonstrate scenario 2.

The E4D MSCRM2013 Excreption Management package contains a sample Plugin project called E4D.CRM.ExceptionMgmtServices.ClientPlugin aimed to demonstrate scenario 3.

Managing Exceptions tools:

Navigate to the Exceptions node in the Settings area to view the Exceptions list. You can feed the unique token displayed in the error message in the Quick Find search box to quickly find the relevant Exception record.
You can export list of Exception records to Excel in order to send out to be reviewed by external developer.

image_thumb14_thumb[3][4]

image_thumb11_thumb[1][4]

image_thumb2_thumb[1]

 

As this solutions is unmanaged, you can can customize and extend it as you wish, here are some ideas:

  • Create a Workflow Rule that will add exceptions to a designated Queue from which Exceptions can be pulled and handled by developers or system administrators.
  • Create a Workflow Rule that will send email to administrators group when critical Exception record is created.
  • Create a Workflow Rule that will send an acknowledgment email to the end user when Exception record is created or handled (status change).
  • Develop a Custom Workflow Activity or Plugin component that will integrate with your ALM application to automatically send exceptions to be handled by the development team.
  • Add JavaScript code to display a nice error message using setFormNotification when error is displayed in entity forms, instead of displaying an alert.

I would like to hear your ideas about extending and improving this solution.

Advertisements

Logging and Handling Microsoft Dynamics CRM 2013 Exceptions – Part 2

In the previous post, I described the business problem of logging and handling implementation level exceptions. In this post, I would like to suggest a solution.

Before you continue reading, note that logging implementation level exceptions is up to your code developer. Although the solution supplies easy methods to log exceptions (to be demonstrated in part 3), nothing will be logged If your custom code does not use the solution components.

Let’s start by defining some business requirements for the suggested solution:

  • Support Microsoft Dynamics CRM 2013 of any deployment type
  • Expose minimum exception details to the user, maximum to the System Administrator
  • Supply the client (user or software component) with a unique correlation code to id each exception instance
  • Require minimum effort from software developers to log exceptions
  • Allow logging and handling client side & server side exceptions in a similar manner
  • Supply System Administrator with an efficient way to search and view exceptions
  • Allow flexible handling when exception is logged: send email notification, move to queue, assign to user/team, send acknowledgment to user etc.

Next, here are the suggested solution major components along with some architecture consideration:

  1. Exception Entity
    This custom entity describes an exception instance details and will be created whenever an exception is logged. Using a custom Exception entity will allow using Microsoft Dynamics CRM UI to easily search and view exception records. A custom entity will also allow great flexibility for handling exceptions by using all Microsoft Dynamics CRM magic: Processes, Queues, Advanced Search, Dashboards, Charts, export to Excel etc.

    The Exception entity will have the following attributes:

    • Name – describes the exception’s raw error message  
    • Created By – reference to the user who initiated the process from which the exception was raised
    • Created On – Date & time on which the exception was logged
    • Friendly Message – the error message that was displayed to the user
    • Unique Token – a unique id assigned to the exception instance and returned to the client along with the friendly message. This token will be used by the System Administrator to correlate the logged exception instance to the error message displayed to the user
    • Priority – describes the exception handling priority
    • Stack Trace – describes the exception’s stack trace which supplies contextual information regarding the calling source function, file etc.
  2. LogException Action
    A custom Action will be used to create an Exception record according to the specified details, generate and assign a unique token and return a friendly message to the client.

    Why Action?

    • Compared to writing custom code, Actions simplify the task of creating and updating an Exception record as it harness the powerful Process tools
    • Action is the only MSCRM mechanism that can receive input parameters and return output parameters in a straight forward manner. Sort of a web service
    • As Action can be accessed from client side (JavaScript code) and server side (Plugins, Custom Workflow Activities, external applications), it provide a single point of implementation
    • Actions allow defining business logic in a declarative manner, so Actions can be easily created and maintained by non developers, as long as the Action signature (parameters and name) is not changed

  3. Unique Token Generator Custom Workflow Activity
    This component will be used by the LogException Action to generate the unique token value. The unique token will be saved to the Exception record and also displayed to the user as part of the managed error message. This will allow the System Administrator to quickly locate the exact exception instance the user has reported.
    As the Process basic tools do not allow generating a unique token, a custom component is required. I prefer a Custom Workflow Activity component as it can be embedded in Actions natural (and transactional) flow, rather than Plugin which is external to the Action. It can also be reused in Workflow Rules and Dialogs.
  4. Sdk.Soap.js
    The Sdk.Soap.js package was recently released by Microsoft as part of the 6.1 SDK. It supplies a comprehensive and intuitive framework for MSCRM JavaScript developers and I recommend it completely.
    One of the package’s tools is the Action Message Generator which automatically generates a JavaScript API for Actions. This API simplifies the execution of Actions from JavaScript and the solution will use it to execute the aforementioned LogException Action from JavaScript Code.
     
  5. ExceptionManagement.js
    This JavaScript Web Resource is used to wrap the functions required to log exception from JavaScript code. 
    In order to use the exception logging functionality, a developer is required to reference this Web Resource in forms event handlers or other Web Resources. This file includes the Sdk.Soap.js library in order to prevent the need for additional reference.
  6. ExceptionManagement.cs
    This C# class is used to wrap the methods required to log exception from c# code written in Plugins, Custom Workflow Activities, external .net applications etc.
    In order to use the exception logging functionality, the developer is required to add this class to his project or compile it into a DLL and reference it.
     
  7. Exception Management Dashboard
    This dashboard is aimed to help the System Administrator manage exceptions with the following components:
    • Exceptions by priority and creation day chart
    • Exceptions by priority and user chart
    • Exceptions by priority chart
    • Critical & High priority exceptions view

 

Finally,  a nice diagram of the solution’s major components:

Solution Components Diagram

Feel free to comment on the architecture and the planned Implementation, I welcome your feedback.

In the next post I will describe the actual Solution and will demonstrate common usage scenarios.

Logging and Handling Microsoft Dynamics CRM 2013 Exceptions – Part 1

In this 3-parts post I would like to suggest a general approach and solution for logging and handling exceptions in Microsoft Dynamics CRM 2013 implementations.

By exceptions, I don’t mean Microsoft Dynamics CRM product core exceptions which occur from time to time. These are logged by various designated repositories (such as Event Viewer and CRM Trace) and beyond our reach anyway, certainly in Online deployments. I do mean unexpected events that arise from custom code written in both server and client side in most Microsoft Dynamics CRM 2013 implementations. These events are usually related to poorly written code, unexpected customization changes or external resources that are beyond your control.

Here are some examples for such exceptions:

  • Custom JavaScript code accessing an attribute of a an object with value of null
  • Custom JavaScript code accessing a field which was removed from the entity form
  • Custom Workflow Activity trying to access an external web service which does not respond or returns an error
  • Plugin code, triggered by an Update event, accessing an attribute which was not updated

Why is it important to log and handle such exceptions? Here are some of the reasons:

  • Bad user experience: When a custom code exception is not handled, it often bubbles to the user interface. This means a vague message is displayed to the end user, a message that he probably can’t handle or tell if and how it affect the business process he is attempting. 
  • Potential business damage: When a user encounters an exception he usually does one of two: ignore it and try again or report the system administrator.
    The first option is bad. It means your application is not healthy and you, as system administrator, are not aware. Beside your users getting frustrated, this may cause data integrity problems, junk data, missed business opportunities or other business related problems.
    It can cost you money!
  • Interrupting your users work: If a user does report an exception to the system administrator, he usually supplies minimum details, less than required to solve the problem without interrupting him to try and reproduce the exception. While some exception details are available to the user (approximate time, attempted business process, error message etc.), other critical details (Internal exception, Stack trace, source component etc.) are hidden from him. 
  • Security breach: Some unmanaged exceptions messages can expose internal mechanisms and supply hackers with details that can help them damage your organization.

Unfortunately, exceptions are part of any business application and cannot be completely avoided. The purpose of the suggested approach is to improve exception handling experience.

So, here is the business problem. In the next post I will describe the suggested solution approach, while the third post will discuss the actual implementation details.

Stay tuned.