Few ways of Handling Exceptions in ASP.NET MVC

Exception handling is one of the major areas of an application development and when it is a web application, it requires additional care so that errors gets handled gracefully without breaking the complete system and relevant information is shown to the users with proper error message. Also making sure that no internal details gets propagated till user when application crashes or error occur because it could be a major security threat. All the exception details and other additional information should be logged so that it can be later used for proper investigation. In this post we will talk about the few options available to handle the exception in ASP.NET MVC and best practices to use them.

In ASP.NET MVC, the request first hits the route handler which identifies the controller and action to be serving the request. We put the whole logic in our controller itself. There are various type of filters in ASP.NET MVC that are also part of the request processing and some time we extend them to put some custom logic based on specific requirement. There is an Exception filter for handling exceptions as well and this Filter is key in handling exceptions in MVC. First let’s see available filters and their order of execution in request processing flow

orderoffilters

So we can see here that there are four filters in total and exception filter executes at end. It means if we use exception filter then it will be caught there whether the exception occurs in Action or even in Authorization/Action/Result filters.

Note – Filters are added as an attribute so it also inherits from ‘System.Attribute’.

Broadly we can say that exceptions may occur in controller or in some cases while processing the routes and filters. But as most of our core logic resides in action so the chances in are most. Before focusing on filters, let’s first discuss one basic way to handle to exception that is part of C#.

Using Try/Catch block

This is C# feature and one of the basic ways to handle exceptions so we can wrap all our code in our Action as below.

try
{
    // Add your code here
}
catch
{
    // Exception Handling code
} 

But there are many issues with this approach and the primary issue is the limitation to single Action. To handle that, we need to put try catch block in each Action of the application which is repeating the same exception handling code which defies the code re-usability logic. It does not mean that we should never use it but there are some scenarios where we require to perform some another activity in case of exception without letting the user know or more specifically if you are calling to some third part services etc. then it might be a good Idea to use this approach.

Global Error Handling

Global error handling is one of the simplest way to handle exceptions at application level. It leverages the Exception Filter to handle exception and applies at application level itself. This is out of the box feature and can be easily set up by following step.

  1. Set customErrors errors as On in web.config as
    <customErrors mode="On"></customErrors>
  2. Have a common error view (in Shared folder with name error.cshtml) which will be shown in case of error aserrorviewHere we see that we get a model of type HandleErrorInfo class which provides the details about that error occurred, controller and action name etc.
  3. Make sure we registere HandleErrorAttribute in Application_Start (Global.asax)method
    RegisterGlobalFilters(GlobalFilters.Filters);
    
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
         filters.Add(new HandleErrorAttribute());
    }
    

    Now if any error occurs then error view will be shown.

Customizing global error handling

We have seen that how easily we can configure the error handling at application level. But what if we want to handle it bit differently. Say we want to save the details in database and/or want to send the email notification when error occurs. We have two options here

  1. Override OnException method :

    We can override OnException method as in our controller as

    protected override void OnException(ExceptionContext filterContext)
    {
        Exception ex = filterContext.Exception;
        // Log Exception ex in database
    
        // Notify  admin team
    
        filterContext.ExceptionHandled = true;
    
        // Setting the View in case of error
        filterContext.Result = new ViewResult()
        {
            ViewName = "CustomErrorView"
        };
    }
    

    Here we can log our exception, send the mail etc. and set our own view that will be shown (like here I used CustomErrorView) in case of error. But this code won’t be reusable and need to write in each controller wherever we need.

  2. To handle it in better way, we need to extend HandleErrorAttribute as
    public class MyCustomHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
                       Exception ex = filterContext.Exception;
                	     // Log Exception ex in database
    
                	     // Notify  admin team
    
                	     filterContext.ExceptionHandled = true;
    
    
            filterContext.ExceptionHandled = true;
    
            filterContext.Result = new ViewResult()
            {
                ViewName = "DVZ"
            };
        }
    }
    

    And instead of registering the default HandleErrorAttribute we need to register the custom one as

    filters.Add(new MyCustomHandleErrorAttribute());
    

    Now this custom error attribute will be used in the whole application.

Handling exception at more Granular level

Till now, we have seen that how can we apply filter at global level. MVC allows us to handle exceptions at more granular level similar at controller and action level as
granularexceptions

For Controller either we can use the default HandleErrorAttribute or we can use the extended attribute similar to MyCustomHandleErrorAttribute and put it at controller as

[MyCustomHandleError]
public class EventController : Controller
{
// Controller code
  	…
}

For Action

public class EventController : Controller
{
	[MyCustomHandleError]
public ActionResult About()
{
	// Action code
}
…
}

Note – Here I have put ‘MyCustomHandleError’ as an attribute. We can use default ‘HandleError’ attribute instead of custom one.

Another variation

There may be some scenarios where we may need to show specific view or details based on the type of exception occurs in Controller/Action. In other words, say if in Controller/Action, if a specific exception occurs, then showing user one view and any other exception occurs then show a different view. Let’s see an example

[HandleError(ExceptionType = typeof(DivideByZeroException), View = "DVZ")]
[MyCustomHandleError]
public ActionResult Create()
{
	// Action code
}

Here if DivideByZeroException occurs then view DVZ will be loaded else default one would be loaded. We can add as many type of exception based on requirement. Also similarly we can apply at Controller level as well.

ExceptionHandled property usage

In OnException method, you must have seen the following line many times.

filterContext.ExceptionHandled = true;

As the name suggests that when we set it true (default: false), then the exception does not propagate further and it is handled in the same method. Say we have put the Exception Filter at action, added a Global exception filer and we did not set the ExceptionHandled filter or set it false then once the exception is caught by action level exception filter that will be thrown further to next level and caught at global filter. Normally when we handle exception we make it false because we have already handled the exception. But there could be few scenarios where we do something with exception details and throw it further so accordingly we need to set this property.

Exception handling outside the scope of MVC

Exceptions are bound to happen and it can always find the way to reach user. We need to block every route. As we know handled the exceptions using MVC framework features but if something happens outside of the MVC scope. As we know that MVC framework is built on top of the ASP.NET platform then we can use the Application_Error method that is available since beginning to handle Application level error. It can be depicted pictorially as
aspnetnmvc

Here we can see that once the control reaches ASP.NET platform, this method can help us so we should handle the exception here as well and we can put all the logging and notification code here as

protected void Application_Error()
{
    Exception ex = Server.GetLastError();
    // Log Exception ex in database

    // Notify  admin team

    // Clear the error
    Server.ClearError();

    // Redirect to a landing page
    Response.Redirect("home/index");
}

Note: Application_Error should not be used in replacement MVC global exception filer, because as soon as you get out of MVC scope, you won’t get its execution context which is very important to provide the relevant details about the exception.

Conclusion

We have discussed various possible ways of handling exceptions. We find that all the exception handling moves around the handle error attribute with many variations. Another two that we discussed: using try catch block and using Application_Error. Best solution for any application would be a combination of these approaches like extend HandleErrorAttribute based on the requirement and use it accordingly. Application Error should be used as if an exception somehow find its way to get out from MVC scope, then it will be caught here. Try Catch block should be really avoided as it just not makes the code ugly but we can miss lots of relevant information that may be helpful in fixing the issue so unless specific case, do not use it.

Advertisements

Getting started Unit Testing in {{AngularJS}} Contd. – Part 20

This post is in continuation of my previous post on Unit Testing in AngularJS where we discussed about the basics of Unit Test in AngularJS, setting up the infrastructure and then wrote couple of unit tests. First we started with test for plain JavaScript method then we wrote an angular application and added unit test for Angular controller. While writing unit test, we also learned basics of Jasmine framework. The link of my previous post is given below

Getting started with Unit Testing in {{AngularJS}} – Part 19

Today we will write unit tests for following components.

  • Angular Service
  • Custom Filters
  • Custom Directive

Note – This post is a part of series of posts on AngularJS and it is 20th one. Click here to view all the post. Apart from that you can also use the navigation links for next and previous post in each post at the bottom to check all.

Testing your Service

As we know that service is an independent object which does some specific work and can be reused at multiple places. We normally used to have many services in our application which does various tasks. These services are the first candidates which should be considered for writing unit tests. Broadly in our service, we do two type of tasks, first where we take some input, write some logic and return the output accordingly. Second, where we connect some third party services via AJAX, process the response and return it. First type of service can be tested easily as normal JavaScript function. We are going to write Unit Test for second type.

We will extend our previous application where we hard coded the values in Angular Controller. Now instead, we will be creating an Angular service which will get the data from server and return that. Let’s see our service

homeModule.factory("TalksService", function ($http, $q) {
    return {
        getTalks: function () {
            // Get the deferred object
            var deferred = $q.defer();
            // Initiates the AJAX call
            $http({ method: 'GET', url: '/home/GetTalkDetails' }).success(deferred.resolve).error(deferred.reject);
            // Returns the promise - Contains result once request completes
            return deferred.promise;
        }
    }
});

Note – In this series of posts on AngularJS, I have written following post where we discussed about Angular Services. To learn more about services, you can refer that

Learning {{AngularJS}} with ASP.NET MVC – Part 4

We have added our service using Factory which uses $http service to get the data from the server. One of the key points is that we are returning a promise here. Now let’s make the required changes in the controller

After these changes, our application would run same as we are now returning the same data server via Web API. Now it’s time to write the Unit Test

Writing Unit Test

There are two new things here, usage of $http Service and returning promise. To test $http service, AngularJS provides a Fake implementation as $httpBackend which helps in mocking the service and setting up the response. To write the test, we need to initialize TalkService and httpBackend that we can inject at before each. Also we need to initialize homeModule as

var TalksServiceFactory, httpBackend;

beforeEach(module("homeModule"));

beforeEach(inject(function($httpBackend, TalksService) {
    httpBackend = $httpBackend;
    TalksServiceFactory = TalksService;
}));

And unit test

    it("Should Return four Talks", function () {
    var talks;
    
        // Setting the mock up mock http response 
        httpBackend
        .expect('GET', '/home/GetTalkDetails')
        .respond(200, [
            { id: '1001', name: 'Real Time Web Applications with SignalR', speaker: 'Brij Bhushan Mishra', venue: 'Hall 1', duration: '45' },
            { id: '1002', name: 'Power of Node.js', speaker: 'Dhananjay Kumar', venue: 'Hall 2', duration: '75' },
            { id: '1003', name: 'Getting started with AngularJS', speaker: 'Brij Bhushan Mishra', venue: 'Hall 1', duration: '60' },
            { id: '1004', name: 'Microsoft Azure - Your cloud destination', speaker: 'Gaurav mantri', venue: 'Hall 1', duration: '45' }
        ]);

        // calling service
        TalksServiceFactory.getTalks().then(function (response) {
            talks = response;
        });

        // Flushing httpBackend
        httpBackend.flush();

        // verification
        expect(talks.length).toBe(4);
    });

Above code is self-explanatory. First we are initializing the mock service, calling the service and finally verifying the response. We can configure httpBackend for different scenarios based on usage of $http in actual service.

Custom Filter

Filter is another one of the most used features of AngularJS. Here we are going to use one custom filter that we wrote in one of previous post where we discussed about Custom Filters. So let’s quickly see the Filter first

homeModule.filter('ConvertoPhone', function () {
    return function (item) {
        var temp = ("" + item).replace(/\D/g, '');
        var temparr = temp.match(/^(\d{3})(\d{3})(\d{4})$/);
        return (!temparr) ? null : "(" + temparr[1] + ") " + temparr[2] + "-" + temparr[3];
    };
});

Note – In this series of posts on AngularJS, I have written following posts where we discussed about Filters and writing custom one. To learn more about it, you can refer the following links

Now to write unit test, we need to inject the $filter and then instantiate our custom filter in the init test. Let’s see our unit test

describe("Filter Tests ->;", function () {

    var filter;
    beforeEach(module('homeModule'));

    beforeEach(inject(function (_$filter_) {
        filter = _$filter_;
    }));

    it('if the number formatted', function () {
        var phoneFilter = filter('ConvertoPhone');

       expect(phoneFilter('1234567891')).toEqual('(123) 456-7891');
    });

});

Custom Directive

Directives are again one of the most important components for AngularJS. Writing Custom Directive is a complex task because it is not just another function which can be injected and called from anywhere. Custom Directives are declaratively used in HTML. As it directly changes the view and also designed in a way to be reused at different views, provided the scope is properly isolated based on requirement, these should be properly tested.

We are going to write two Custom Directives : First would be a simple one and another using isolate scope and we will write unit test for both the cases. First directive is an element directive which reads some information from scope and replaces the directive with the provide html in directive as

homeModule.directive('myelementdirective', function () {
    var directive = {};
    directive.restrict = 'E'; //restrict this directive to elements
    directive.template = "Hello {{name}} !! Welcome to this Angular App";
    return directive;
});

Note – In this series of posts on AngularJS, I have written following posts where we discussed about writing custom directives. To learn more about it, you can refer the following links

Writing Unit Test

Writing unit test is tricky for directives because every custom directive is first complied which renders the html then other actions like binding, any user actions are performed. There is a digest cycle which runs and responsible for any binding or any other initialization before a directive appears on page.  So when writing unit test we ourself need to compile the directive using compile service and create a specific scope if required. Then run the digest cycle to make it in similar state as on UI. For that we need to initialize the scope, compile service by injecting it using beforeEach. Now let’s see our test

 var compileService, rootScope;
       
    beforeEach(module('homeModule'));

    // Store references to $compile and $rootScope so they can
    // be uses in all tests in this describe block
    beforeEach(inject(function (_$compile_, _$rootScope_) {
        compileService = _$compile_;
        rootScope = _$rootScope_;
        rootScope.talk = {
            name: 'abc', duration: '25m'
        };
        rootScope.name = 'Brij' ;
    }))

    it('My element Custom Directive defined', function () {

        var compiledDirective = compileService(angular.element('<myelementdirective/>'))(rootScope);

        rootScope.$digest();

        expect(compiledDirective).toBeDefined();

    });

Here we are compiling the directive and running the digest cycle and checking whether it is defines. Then we can write another test which checks whether the correct html is rendered or not as


    it('My element Custom Directive renders proper html', function () {

        var compiledDirective = compileService(angular.element('<myelementdirective/>'))(rootScope);

        rootScope.$digest();

        expect(compiledDirective.html()).toContain("Hello Brij !! Welcome to this Angular App");
    });
Angular App");
    });

Testing Custom Directive with isolated scope

Now we are going to write another directive with isolate scope. If you know or referred my previous post then we find that three types of isolated scope are available in Custom Directives which is also known as Local scope properties. We are going to write two way binding scope where the data is always in sync with parent regardless where it is getting changed. So let’s see the custom directive first


homeModule.directive('bindcustomdirective', function () {
    var directive = {
        restrict: 'E', // restrict this directive to elements
        scope: { talkinfo: '=' },
        template: "<input type='text' ng-model='talkinfo.name'/>" +
            "


<div>{{talkinfo.name}} : {{talkinfo.duration}}</div>



",
    };
    return directive;
});

Here talkinfo gets initialize with the scope passed via an attribute while using Directive as

 <bindcustomdirective talkdetails="talk" />

As in the template, we have input which allows to change the scope object, this reflects in the parent scope as well.

Writing Unit Test

To write the unit test, most of things would be same as above like initialization of compiler service, scope and assign some initial value to talk object in parent scope. So lets move to the test itself

 it('Bind Custom Directive defined', function () {

    var compiledDirective = compileService(angular.element(' <bindcustomdirective talkinfo="talk" />'))(rootScope);

    rootScope.$digest();

    var isolatedScope = compiledDirective.isolateScope();

    expect(isolatedScope.talkinfo).toBeDefined();
});

Here we got the compiled directive using compiler service and run the digest cycle same as earlier one. One extra line added to get the isolate scope from the compiled directive and checking whether talkInfo is defined.

We will write another test and here we will check that if we change the isolated object’s property whether that get reflected in parent scope or not as

it('Bind Custom Directive two way binding check', function () {
    var compiledDirective = compileService(angular.element(' <bindcustomdirective talkinfo="talk" />'))(rootScope);

    rootScope.$digest();

    compiledDirective.isolateScope().talkinfo.name = "Building modern web apps with ASP.NET2";

    expect(rootScope.talk.name).toEqual("Building modern web apps with ASP.NET2");
});

Conclusion

We have written the unit tests few very important components of AngularJS. Although many more test could be written and even these components vary based on requirement, accordingly different unit test may be required. But in this post, I tried to provide the basics of writing unit test for these test. Do share your feedback or face any difficulty for writing unit test for any specific component. I will try to answer that.

Cheers,
Brij

Next Post ==>

How to use Angular Filter in Controller, Factory, Service – Part 15

In last two posts, we explored about the Filters and saw that how easily we can create custom filter and use as Angular predefined filters. We have used these filters in views for a single as well as an array of items. This is a normal scenario but there could be some cases where you need to use these filters in other components like Controllers, Factory, and Services etc. I have seen many questions around this on different online forums. So I thought to discuss it in detail.

If you are new to Angular Filter or even if you have some idea about, I will highly recommend you to go through my below two earlier Posts then continue. In this post, I will use the same examples that I used in my previous two posts as well.

Exploring Filters in {{AngularJS}} – Part 13

Exploring Filters in {{AngularJS}} Contd. : Custom Filters – Part 14

Note – This post is a part of series of posts on AngularJS and it is fifteenth one. Click here to view all the post. Apart from that you can also use the navigation links for next and previous post in each post at the bottom to check all. Continue reading

Exploring Filters in {{AngularJS}} Contd. : Custom Filters – Part 14

This post is in continuation of my previous post regarding Filters. (Click here to go to previous post). In last post we discussed about the basics of Angular Filters and found that how easy is to use the predefined filters with examples. This post is also fourteenth post in the series of AngularJS and to see all the previous posts, click here.

In this post, we will be discussing about custom Filter, its uses and create a few custom ones. Also we’ll try to explore some more flavors of the filters. We discussed two main types of Filters in previous post, one that transforms a single item in different format. Another one that can be applied on array of items which produces another array after applying Filter .The resultant array could have same or less number of elements and contain same or transformed data. As we discussed in my earlier posts that Modules in Angular are like containers. It is a top level element and contains all the components of AngularJS. So every custom items must be registered with it. Same is true here as well. Let’s start creating a filter of first type, we already saw some Filters like uppercase, lowercase, currency etc. Now we are going to create a Filter which currently does not exist. It takes a string of numbers and convert into phone number format. Excited?

Continue reading

Exploring Filters in {{AngularJS}} – Part 13


AngularJS is one of the hottest technologies currently in market. Every web project built on any platform whether .NET, JAVA, PHP or any other, all are just embracing it. It is because the kind of power, flexibility, openness and many other awesome features provided by AngularJS. But I would say even we are using this framework in most of our web applications, but we are not leveraging the real power of of many features. In this post, I am going to discuss about Filters and how to get best out of it.

This post is again in the series of Posts of AngularJS and it is thirteenth in the list. To go though the previous posts in the series, click here.

Filters is one of key features provided by AngularJS and almost used in every web application. In this post, we will be exploring it with bunch of examples. We’ll start from basics then dig deep and create our own custom filter at the end.

What is Filter Continue reading