How to properly throw and handle exceptions using web services

I am following MVC example on my application server. I am trying to throw an exception, but it was not thrown correctly.

Here is the code from the controller:

[HttpPost]
public IHttpActionResult PostAddSuperUser(SuperUserViewModel SU)
{
    try
    {
        //more code
        blHandler.addSuperUser((SuperUser)SU.user, SU.Password);
        return Ok();
    }
    catch (EUserAlreadyExist ex)
    {
        var resp = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
        resp.Content = new StringContent(string.Format("Already exist ", SU.user.Mail));
        resp.ReasonPhrase = "Already exist";
        throw new HttpResponseException(resp);
    }

      

The client side then calls it like this:

try{
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("http://localhost:50687/");

            HttpResponseMessage response = await client.PostAsJsonAsync<SuperUserViewModel>("/api/SuperUser/PostAddSuperUser", SUVM);

            if (response.IsSuccessStatusCode)
            {
                new SuccesPupUp("", "SuperUser " + SupUserName + " was added");
            }
            this.Close();
        }
}
catch (HttpResponseException Exc)
{
    new ErrorPopUp("", Exc.Message);
}

      

Accordingly, this I throw it right, but when I run it, I got this errorenter image description here

How can I fix this?

EDIT: I want to pass the exception to the client side so that it can prompt the user for a new email address

+3


source to share


2 answers


The problem is in this block of code (seems obvious, but bear with me):

  catch (EUserAlreadyExist ex)
    {
        var resp = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
        resp.Content = new StringContent(string.Format("Already exist ", SU.user.Mail));
        resp.ReasonPhrase = "Already exist";
        throw new HttpResponseException(resp);
    }

      

What happens is that you are grabbing the EUserAlreadyExist exception from the above attempt and then throwing a new exception with no accompanying block try-catch

. So this means that just because you threw an exception from the catch, it won't automatically magic catch it, you will have to have a separate one try-catch

inside your catch



Going further, the client call to this will try-catch

also not catch the thrown exception, because they (the operators catch

) catch different types of exceptions other than the one that is thrown.

To fix this, you need an exception, which in this case will throw an exception HttpResponseException

. This means that your code might look something like this:

  catch (EUserAlreadyExist ex)
    {
    try{
        var resp = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
        resp.Content = new StringContent(string.Format("Already exist ", SU.user.Mail));
        resp.ReasonPhrase = "Already exist";
        throw new HttpResponseException(resp);
       }
       catch(HttpResponseException ex2)
       {
         //do something here with the exception
       }
    }

      

0


source


Server side code shouldn't catch the exception and re-throw it - what's the point? Just let it bubble up to the client. This is the beauty and power of exceptions. The problem is that MVC wants to return a view code or HTTP status code, not rich, strongly typed exception information.

You seem to be using the MVC pattern in a rich client (client-server) situation, which doesn't make sense. MVC is best suited for thin client situations where the server is serving views and the client is just displaying them. When you have a rich client, the MVVM pattern makes more sense. The server can serve View Models (data) and the client can handle all user interaction, views, etc.

Consider using the MVVM approach (with WCF) instead of MVC. Then both the client and the server will have a general idea of ​​the types of exceptions that can be thrown. Server can throw, client can catch, easily.



Then your client code will be as simple as:

try
{
    c.AddSuperUser(SUVM);
}
catch (Exception e)
{
    // etc
}

      

where c is the WCF proxy.

0


source







All Articles