2

I am intentionally making a violation of a unique constraint in my database, and trying to handle an exception.

This among else is in my form:

HttpResponseMessage response = KorisniciService.PostResponse(k);
                if (response.IsSuccessStatusCode)
                {
                    MessageBox.Show(Messages.add_usr_succ);
                    DialogResult = DialogResult.OK;
                    Close();
                }
                else
                {
                    string message = response.ReasonPhrase;
                    if (string.IsNullOrEmpty(Messages.ResourceManager.GetString(response.ReasonPhrase)))
                        message = Messages.ResourceManager.GetString(response.ReasonPhrase);


                    MessageBox.Show("Error code: " + response.StatusCode + " Message: " + message);
                }

My controller:

public IHttpActionResult PostKorisnici(Korisnici obj)
        {
            if (!ModelState.IsValid)
                return BadRequest();
            try
            {
                obj.KorisnikId = Convert.ToInt32(dm.esp_Korisnici_Insert(obj.Ime, obj.Prezime, obj.Email, obj.Telefon, obj.KorisnickoIme, obj.LozinkaSalt, obj.LozinkaHash, obj.Status, obj.Adresa, obj.GradId).FirstOrDefault());
            }
            catch (EntityException ex)
            {
                throw CreateHttpResponseException(Util.ExceptionHandler.HandleException(ex), HttpStatusCode.Conflict);
            }


            foreach (var item in obj.Uloge)
            {
                    dm.esp_KorisniciUloge_Insert(obj.KorisnikId, item.UlogaId);
            }
            return CreatedAtRoute("DefaultApi", new { id = obj.KorisnikId }, obj);
        }

HttpResponseException making function:

private HttpResponseException CreateHttpResponseException(string reason, HttpStatusCode code)
        {


            HttpResponseMessage msg = new HttpResponseMessage()
            {
                StatusCode = code,
                ReasonPhrase = reason,
                Content = new StringContent(reason)
            };
            return new HttpResponseException(Request.CreateResponse(msg));
        }

Exception handler class:

public class ExceptionHandler
    {
        public static string HandleException(EntityException error)
        {

            SqlException ex = error.InnerException as SqlException;

                switch (ex.Number)
                {
                    case 2627:
                    {
                        return GetConstraintExceptionMessage(ex);
                    }
                    default:
                        return error.Message + "(" + error +")";
                }
        }
        /*Message "Violation of UNIQUE KEY constraint 'CS_KorisnickoIme'. Cannot insert duplicate key in object 'dbo.Korisnici'. The duplicate key value is (farish).\r\nThe statement has been terminated."    string*/

        private static string GetConstraintExceptionMessage(SqlException error)
        {
            string newMessage = error.Message;
            int startIndex = newMessage.IndexOf("'");
            int endIndex = newMessage.IndexOf("'", startIndex + 1);

            if (startIndex>0 && endIndex>0)
            {
                string constraintName = newMessage.Substring(startIndex + 1, endIndex - startIndex - 1);

                if (constraintName == "CS_KorisnickoIme")
                    newMessage = "username_con";
                else if (constraintName == "CS_Email")
                    newMessage = "email_con";


            }
             return newMessage;
        }

So when I produce an error, instead of a popup window (which shows up fine in a tutorial video) I get a System.Web.Http.HttpResponseException in a first catch block of my post method and nothing passed back to my form.

Faski
  • 31
  • 1
  • 7

1 Answers1

0

I think because the exception is being thrown and not inside a try/catch block, or the catch block receiving the CreateHttpResponseException, is absorbing it and not providing a response object.

EDIT Can you post the code for KorisniciService.PostResponse?

and nothing passed back to my form

And what is the eventual result? From the form code you have posted it should either popup message box with success message, or popup message box with fail message. What actually happens?

2nd EDIT

Following further information, use this in your form code...

try
{
    HttpResponseMessage response = KorisniciService.PostResponse(k);

    if (response.IsSuccessStatusCode)
    {
        MessageBox.Show(Messages.add_usr_succ);
        DialogResult = DialogResult.OK;
        Close();
    }
}
catch(HttpResponseException ex)
{
    string message = ex.ReasonPhrase;

    if (string.IsNullOrEmpty(Messages.ResourceManager.GetString(ex.ReasonPhrase)))
        message = Messages.ResourceManager.GetString(ex.ReasonPhrase);


    MessageBox.Show("Error code: " + ex.StatusCode + " Message: " + message);
}
Allumearz
  • 259
  • 2
  • 6
  • You can ignore that part of my question, since the reason nothing is passed back to my form is the exception thrown in the first catch block of my post method in the controller. – Faski Dec 02 '18 at 17:00
  • Then in that case, it is because you do not have a try... catch block in your form code... you are getting an uncaught exception which is standard behaviour. – Allumearz Dec 02 '18 at 18:40
  • For some reason I cannot catch HttpResponseException, only HttpRequestException, I have added all the references, but still no luck. HttpRequestException doesn't have the required members. I have also tried catching a general exception and casting but no required members available. – Faski Dec 02 '18 at 20:23
  • Since I have 2 projects, I was missing some packages in the UI project, after I have added your code, in the form I still get an exception on the same place as before: " System.Web.Http.HttpResponseException: 'Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.'" **Here's the response:** {StatusCode: 409, ReasonPhrase: 'username_con', Version: 1.1, Content: System.Net.Http.StringContent, Headers: { Content-Type: text/plain; charset=utf-8 }} – Faski Dec 02 '18 at 21:15
  • So basically an exception is created since 409 is a Conflict code, and the reason phrase is good, it just doesn't get passed back to the form, but rather stops the execution in the catch block showing an uncaught exception. – Faski Dec 02 '18 at 21:28
  • It stops the execution in the catch block...? If it's in the catch block then it has caught the error... Are you sure you don't mean in the try block? – Allumearz Dec 03 '18 at 00:26
  • I am positive, it stop the execution in the catch block and pointing to this in my controller post method `throw CreateHttpResponseException(Util.ExceptionHandler.HandleException(ex), HttpStatusCode.Conflict);` – Faski Dec 03 '18 at 01:06
  • Do you have the setting in VS turned on to break on all exceptions? – Allumearz Dec 03 '18 at 01:13
  • I think I do, but is turning it off a valid solution to the problem? When I send the code in for the review, it might throw them the exception (most probably will). – Faski Dec 03 '18 at 17:59
  • But if VS is set to break on all exceptions, then the code is just paused in the debugger when an exception occurs, even if the exception is handled properly. Are you sure you're not misinterpreting the behaviour of VS and that if you "continue" running, the code returns to your form properly? – Allumearz Dec 03 '18 at 23:57
  • I turned it off not to break on this type of the exception and now **nothing** happens when i click on the button which saves the data (uses the post method), it just keeps running and does nothing. – Faski Dec 04 '18 at 14:04
  • I removed the try - catch block from my form, leaving only a if/else as it was on the beginning, turned off breaking on this type of exception and voila, it works! Thank you for your help! – Faski Dec 04 '18 at 15:20