3

I'm following MVC pattern in my Application server. I'm trying to throw an exception but its not been properly thrown.

Here is the code from 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);
    }

Then the client side calls it as follow:

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);
}

According to this this I'm throwing it correctly, but when I run it I got this errorenter image description here

How can I fix it?

EDIT: I want to throw the exception to the client side, so as to it could ask the user for a new email address

6
  • 1
    as you can see it throws HttpResponseException which you're not catching, just add first catch - catch(HttpResponseException ex) Commented May 28, 2015 at 20:26
  • 3
    Since you are asking about "properly handling exceptions", please note its a "best practice" to name your exceptions with a suffix of Exception instead of a prefix "E". For example, EInvalidPassword should be named InvalidPasswordException, yes, its longer, but its much more evident what it is. Commented May 28, 2015 at 20:33
  • in catch() you must handle HttpResponseException, not EUserAlredyExist, becouse you dont throw EUserAlredyExist exception. Commented May 28, 2015 at 20:38
  • This question is related to stackoverflow.com/questions/19287426/…. If you throw an Exception from within a catch block, and there is no catch block outside of that one, the Exception is unhandled. Commented May 28, 2015 at 21:38
  • 1
    @DanielPetrovaliev, it's likely that his blHandler.addSuperUser() method could throw the EUserAlreadyExist exception, which is why he's catching it. Commented May 28, 2015 at 21:44

2 Answers 2

0

The problem is within 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);
    }

Whats happening is that you are catching an EUserAlreadyExist exception from the above try and then throwing a new exception without an accompanying try-catch block. So this means that just because you threw an exception within a catch, it won't auto-magically catch it, you would have to have a separate try-catch within your catch

Going further with this, the client-side call to this try-catch also won't catch the thrown exception because they (the catch statements) are catching different types of exceptions than what is being thrown.

To fix it would require you catching the exception that is being thrown in this case a HttpResponseException exception. So that would mean 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
       }
    }
Sign up to request clarification or add additional context in comments.

3 Comments

This doesn't seem right, why would you throw an exception and then catch it right away?
Per @Rodrigo's question and code, this answer technically should work, but I would agree it doesn't make much sense to throw an exception in this way.
@Pseudonym all I want to do with my try catch on server side is to throw the exception to the client side, so how will catching my own exception help me to do it? As I see, if I add a new try-catch, I'll catch it again but I still don't know what to do with it or how to send it to the client side
0

Server side code should not need to catch the exception and re-throw it - what's the point? Just let it bubble up to the client. That's the beauty and power of exceptions. The trouble is MVC wants to return a View or an HTTP Status Code, not rich, strongly typed exception information.

You appear to be using MVC pattern in a rich client (client-server) situation, which makes no sense. MVC is best suited to thin client situations whereby the server serves up views, and the client just renders them. When you have a rich client, the MVVM pattern makes more sense. Server can serve up View Models (data) and client can take over all the user interaction, views etc.

Consider using an MVVM approach (with WCF) instead of MVC. Then both client and server will have a common understanding of the exception types that can be thrown. Server can throw, client can catch, easy.

Your client code would then be as simple as:

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

where c is the WCF client proxy.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.