none
DB exception not caught in Entity Framework

    Question

  •  

    I have written a few CRUD sprocs for my entities and mapped them. Everything works fine. I can create and delete etc.. Unfortunately I have noticed that EF does not seem to 'receive' exceptions thrown by the DB (SQl server 2005). I deliberately raised an error like this:

    RAISERROR('Bla bla bla', 16, 1) WITH NOWAIT

    but I did not get an exception/the error message.

    I am using code like this:

    using(DBEntities context = new DBEntities())
                {
                    try
                    {
                        Link l = (Link) context.ItemSet.Where(link => link.item_uid == item_uid).First();
                        context.DeleteObject(l);
                        context.SaveChanges();
                    }
                    catch (Exception ex)
                    {
                        errorMsg = "Ex " + ex.Message.ToString() + "\n"; ;
                        errorMsg = errorMsg + ex.InnerException.Message.ToString();
                    }
                }

    Am I doing something wrong? Why do I not catch the deliberate exception? Thanks.

    Christian
    Friday, November 14, 2008 11:25 AM

Answers

  • Hi Christian, Our team verified that the scenario were CRUD procs are throwing a RAISERROR surfaces DbException as expected. Are you sure that the Delete sproc in the scenario above is the one throwing the RAISERROR?

     

    Thanks,

    Sushil.

    Tuesday, November 18, 2008 5:49 PM

All replies

  • Hi Christian, Our team verified that the scenario were CRUD procs are throwing a RAISERROR surfaces DbException as expected. Are you sure that the Delete sproc in the scenario above is the one throwing the RAISERROR?

     

    Thanks,

    Sushil.

    Tuesday, November 18, 2008 5:49 PM
  • I have come across a similar issue on an update. A Table CHECK CONSTRAINT was thrown from the DB but the returned exception had no details of this.I tracked it down via Sql Profiler to get the generated  T-SQL , then copied this to Query Analyser to figure out the error. This is the T-SQL:

     

    exec sp_executesql N'update [dbo].Computer
    set [Status] = @0, [Date_Updated] = @1, [UserID] = @2, [PC_ID] = @3, [Reject_Msg] = @4, [Seq_No] = @5, [Client_No] = @6, [Co_No] = @7, [Co_Name] = @8, [Stock_Age_1] = @9, [Age_1_Depreciation] = @10, [Stock_Age_2] = @11, [Age_2_Depreciation] = @12, [Sell_In_Time] = @13, [Sell_Thru_Time] = @14, [Back_List_Time] = @15, [Returns_Lag] = @16, [Staging_ID] = @17
    where ([Co_ID] = @18)
    ', N'@0 tinyint,@1 datetime,@2 varchar(11),@3 varchar(9),@4 varchar(8000),@5 int,@6 tinyint,@7 varchar(2),@8 varchar(27),@9 int,@10 int,@11 int,@12 int,@13 int,@14 int,@15 int,@16 int,@17 int,@18 int', @0 = 0, @1 = 'Oct 31 2008  2:38:00:000PM', @2 = 'DWMaintUser', @3 = 'R-HC05105', @4 = '', @5 = 1, @6 = 1, @7 = '01', @8 = 'HarperCollins Publishers   ', @9 = 12, @10 = 70, @11 = 11, @12 = 70, @13 = 0, @14 = 0, @15 = 0, @16 = 0, @17 = 0, @18 = 1

     

    And this is the Query Analyser output:

    Server: Msg 547, Level 16, State 1, Line 1
    UPDATE statement conflicted with TABLE CHECK constraint 'Company Stock Age 2 > Stock Age 1'. The conflict occurred in database 'Client_01', table 'Co'.
    The statement has been terminated.

    I was expecting this to be in the InnerException but no, nothing there ;-(

     

    I'm now wondering how to proceed with this. I'm thinking I would need to "copy" logic rules from the DB to the Web Service which is totally the wrong way to go about this. I'm looking forward to your suggestions.

     

    Nick

     

    Thursday, November 20, 2008 12:39 PM
  • Think I have the way of handling this. In the .svc.cs file you need to handle the exception as shown here. This returned the error I was expecting and I was able to feed the error back to client as shown below:

     

    protected override void HandleException(HandleExceptionArgs args)

    {

    if (args.Exception is UpdateException)

    {

    UpdateException ue = (UpdateException)args.Exception;

    args.Exception = new DataServiceException("Update Failed. Error is " + args.Exception.InnerException.Message);

    }

    }

     

    I am now able to tell the end-user that the TABLE CHECK CONSTRAINT termninated the update. I'm happier now :-)

     

    This code is referred to in article http://msdn.microsoft.com/en-us/library/cc907912.aspx in the Error Handling section

     

    Nick

    Thursday, November 20, 2008 1:48 PM
  • I got it.

    EF handles the first result of query only. Therefore, this sproc will be fine:

    CREATE PROCEDURE [dbo].[Test]
    AS
    BEGIN
        RAISERROR ('Joe The Uncatchable', 16, 1)
        SELECT 1 AS id
    END

    while this one will NOT generate an exception:

    CREATE PROCEDURE [dbo].[Add_Test_Record]
    AS
    BEGIN
     SELECT 1 AS id
        RAISERROR ('Joe The Uncatchable', 16, 1)
    END
    It's because of EF is ignoring second result containing error.

    Friday, March 22, 2013 9:31 AM