First Last

First Last

  • NA
  • 648
  • 73.2k

Asp.net TRY CATCH not working when surrounding stored procedure

Jan 2 2021 5:23 PM
In my web api data access layer, the Asp.net TRY CATCH is NOT catching the fail of the stored procedure. Note: this template of code is used threw out my web api data access layer and works fine. Just not in this case. Weird!!
 
I expect the stored procedure to fail as there are no rows that meet the criteria. So in that case, I raise an error (RAISERROR) and it writes an entry to my error log table.
 
This happens when I execute it via SSMS or running my web app that calls the web api that executes the stored procedure.
 
The error log table with 2 entries. 1 from running the stored procedure via SSMS and the other from running my web app.
 
 The problem is the web api data access layer code execution does NOT catch the error returned by the stored procedure. It does NOT go into the CATCH.
 
Here is the web api data access layer function called from my web api controller. It has the TRY CATCH that is NOT working properly: 
  1. public List GetBlogCategorysInBlogsPublishedList(string userName, string ipAddress)  
  2.       {  
  3.           string userFriendlyMessage = "Unable to get the blog categorys in the blogs published list. We have been notified and are working to resolve this. Please do not continue.";  
  4.   
  5.           List blogPublishedCategoryList = new List();  
  6.   
  7.           SqlDataReader blogCategorysInBlogsDataReader = null;  
  8.   
  9.           try  
  10.           {  
  11.               dbFunc.OpenDB();  
  12.   
  13.               SqlCommand cmd = new SqlCommand("dbo.GetBlogCategorysInBlogsPublished", dbFunc.objConn);  
  14.               cmd.CommandType = CommandType.StoredProcedure;  
  15.               cmd.Parameters.Clear();  
  16.   
  17.               cmd.Parameters.AddWithValue("@a_UserName", userName);  
  18.               cmd.Parameters.AddWithValue("@a_IpAddress", ipAddress);  
  19.   
  20.               blogCategorysInBlogsDataReader = cmd.ExecuteReader();  
  21.   
  22.               // Loop thru the results returned.  
  23.               while (blogCategorysInBlogsDataReader.Read())  
  24.               {  
  25.                   // Add to the list of BlogPublishedCategory - creates a new row for the collection.  
  26.                   blogPublishedCategoryList.Add(new BlogPublishedCategory  
  27.                   {  
  28.                       BlogCategoryId = Convert.ToInt32(blogCategorysInBlogsDataReader["BlogCategoryId"]),  
  29.                       BlogCategoryDescr = blogCategorysInBlogsDataReader["BlogCategoryDescr"].ToString(),  
  30.                   });  
  31.               }  
  32.   
  33.               // Return the blogPublishedCategoryList object.  
  34.               return blogPublishedCategoryList;  
  35.           }  
  36.           catch (SqlException sqlex)  
  37.           {  
  38.               if (sqlex.Message.Contains("Critical"))  
  39.               {  
  40.                   // A "critical" error coming from the stored procedure.  
  41.                   // So, send an alert email to a staff member (an Admin), but do NOT process the error log as it has been done already   
  42.                   // in the stored procedure.  
  43.   
  44.                   currentDateTime = DateTime.Now;  
  45.                   sendAlertEmailResult = SendAlertEmailToStaff(currentDateTime, userName, ipAddress);  
  46.   
  47.                   if (sendAlertEmailResult == "")  
  48.                   {  
  49.                       throw new Exception(userFriendlyMessage);  
  50.                   }  
  51.                   else  
  52.                   {  
  53.                       throw new Exception("In DataAccessLayer/GetBlogCategorysInBlogsPublishedList(). Sending an alert email for the initial sql exception error: " + sqlex.Message + ". Now getting this error: " + sendAlertEmailResult);  
  54.                   }  
  55.               }  
  56.               else  
  57.               {  
  58.                   // Not coming from the stored procedure.   
  59.                   errorMessage = "Sql Exception Error in DataAccessLayer/GetBlogCategorysInBlogsPublishedList(). Using 'GetBlogCategorysInBlogsPublished' s/p. Error: " + sqlex.Message;  
  60.   
  61.                   // Log the error and send an alert email.  
  62.                   currentDateTime = DateTime.Now;  
  63.                   processErrorLogAndSendAlertEmailResult = ProcessErrorLogAndSendAlertEmail(currentDateTime, userName, errorMessage, additionalInfoForLog, ipAddress);  
  64.   
  65.                   if (processErrorLogAndSendAlertEmailResult != "")  
  66.                   {  
  67.                       throw new Exception("Error in DataAccessLayer/GetBlogCategorysInBlogsPublishedList(). Using 'GetBlogCategorysInBlogsPublished' s/p. Logging the initial sql exception error: " + sqlex.Message + ". Now getting this error: " + processErrorLogAndSendAlertEmailResult);  
  68.                   }  
  69.                   else  
  70.                   {  
  71.                        throw new Exception(userFriendlyMessage);  
  72.                   }  
  73.               }  
  74.           }  
  75.           catch (Exception ex)  
  76.           {  
  77.               errorMessage = "Error in DataAccessLayer/GetBlogCategorysInBlogsPublishedList(). Using 'GetBlogCategorysInBlogsPublished' s/p. Error: " + ex.Message;  
  78.   
  79.               // Log the error and send an alert email.  
  80.               currentDateTime = DateTime.Now;  
  81.               processErrorLogAndSendAlertEmailResult = ProcessErrorLogAndSendAlertEmail(currentDateTime, userName, errorMessage, additionalInfoForLog, ipAddress);  
  82.   
  83.               if (processErrorLogAndSendAlertEmailResult != "")  
  84.               {  
  85.                   throw new Exception("Error in DataAccessLayer/GetBlogCategorysInBlogsPublishedList(). Using 'GetBlogCategorysInBlogsPublished' s/p. Logging the initial error: " + ex.Message + ". Now getting this error: " + processErrorLogAndSendAlertEmailResult);  
  86.               }  
  87.               else  
  88.               {  
  89.                   throw new Exception(userFriendlyMessage);  
  90.               }  
  91.           }  
  92.           finally  
  93.           {  
  94.               if (blogCategorysInBlogsDataReader != null)  
  95.               {  
  96.                   // Close the reader.  
  97.                   blogCategorysInBlogsDataReader.Close();  
  98.               }  
  99.   
  100.               // Close the database.  
  101.               dbFunc.CloseDB();  
  102.           }  
  103.       }  
 The GetBlogCategorysInBlogsPublished stored proc:
 
  1. USE [DBGbngDev]  
  2.     GO  
  3.   
  4.     SET ANSI_NULLS ON  
  5.     GO  
  6.     SET QUOTED_IDENTIFIER ON  
  7.     GO  
  8.   
  9.     IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].   
  10.     [GetBlogCategorysInBlogsPublished]') AND type in (N'P', N'PC'))  
  11.         BEGIN  
  12.            DROP PROCEDURE [dbo].GetBlogCategorysInBlogsPublished  
  13.         END  
  14.     GO  
  15.   
  16.     CREATE procedure [dbo].[GetBlogCategorysInBlogsPublished]   
  17.   
  18.     @a_UserName                                                varchar(250) = NULL,  
  19.     @a_IpAddress                                               varchar(250) = NULL  
  20.   
  21.     AS   
  22.     BEGIN  
  23.   
  24.     DECLARE @RowCount                  int,  
  25.             @ReturnCode                int,  
  26.             @CurrentDateTime           datetime,    
  27.             @Message                   varchar(max) = '',  
  28.             @ApiMessageOut             varchar(max),  
  29.             @ApiAccessSwitchOut        bit  
  30.   
  31.     DECLARE @ErrorLine          AS INT;  
  32.     DECLARE @ErrorMessage       AS VARCHAR(2048);  
  33.     DECLARE @ErrorNumber        AS INT;   
  34.     DECLARE @ErrorSeverity      AS INT;   
  35.     DECLARE @ErrorState         AS INT;   
  36.     DECLARE @DatabaseName       AS VARCHAR(255);  
  37.     DECLARE @ServerName         AS VARCHAR(255);  
  38.     DECLARE @ErrorDescription   AS VARCHAR(MAX);  
  39.     DECLARE @CRLF               AS VARCHAR(2);  
  40.   
  41.     SELECT @CurrentDateTime = GETDATE()  
  42.           
  43.     BEGIN TRY  
  44.   
  45.        SET NOCOUNT ON;  
  46.   
  47.        IF ( ( @a_UserName  = '' OR @a_UserName  IS NULL )   
  48.        OR ( @a_IpAddress = '' OR @a_IpAddress IS NULL ) )  
  49.           BEGIN  
  50.              SELECT @Message = 'Critical Error - procedure GetBlogCategorysInBlogsPublished - invalid   
  51.              parameters. They cannot be null or empty.'   
  52.   
  53.              IF ( @a_UserName = '' OR @a_UserName IS NULL )  
  54.                  BEGIN  
  55.                     SET @a_UserName = 'No "user name" parameter provided.'  
  56.                  END  
  57.   
  58.              IF ( @a_IpAddress = '' OR @a_IpAddress IS NULL )  
  59.                  BEGIN  
  60.                     SET @a_IpAddress = 'No "ip address" parameter provided.'  
  61.                  END  
  62.   
  63.             RAISERROR (@Message, 16, 1)  
  64.           END  
  65.        ELSE  
  66.           BEGIN  
  67.                -- Do the API security check. If this user is valid, you can continue with further  
  68.                processing.  
  69.                SELECT @ReturnCode = -1  
  70.                EXECUTE @ReturnCode = dbo.GetApiAccess  
  71.                                   @CurrentDateTime,  
  72.                                   @a_UserName,  
  73.                                   @a_IpAddress,  
  74.                                   @a_ApiAccessSwitchFromGet = @ApiAccessSwitchOut OUTPUT,  
  75.                                   @a_ApiMessageFromGet = @ApiMessageOut OUTPUT  
  76.       
  77.                IF @ReturnCode = -1  
  78.                     BEGIN   
  79.                        RAISERROR ('Critical Error - procedure GetBlogCategorysInBlogsPublished failed during execute of procedure GetApiAccess.', 16, 1 )  
  80.                     END  
  81.           
  82.                -- Web api access was granted.   
  83.                IF @ApiAccessSwitchOut = 1  
  84.                    BEGIN      
  85.                        SELECT DISTINCT (a.BlogCategoryId) as BlogCategoryId  
  86.                                        ,a.BlogCategoryDescr as BlogCategoryDescr  
  87.                        FROM dbo.BlogCategory a  
  88.                        JOIN dbo.Blog b On ( a.BlogCategoryId = b.BlogCategoryId )  
  89.                        WHERE ( b.PublishSwitch = 1 AND b.CanBeSeenSwitch = 1 )  
  90.                        ORDER BY a.BlogCategoryId asc    
  91.   
  92.                        SELECT @ReturnCode = @@ERROR,  
  93.                               @RowCount = @@ROWCOUNT  
  94.   
  95.                        IF @ReturnCode <> 0  
  96.                            BEGIN   
  97.                                SELECT @Message = 'Critical Error - procedure GetBlogCategorysInBlogsPublished failed during the select.'  
  98.                                RAISERROR (@Message, 16, 1)  
  99.                            END  
  100.                
  101.                        IF @RowCount = 0  
  102.                            BEGIN  
  103.                                SELECT @Message =  'Critical Error - procedure GetBlogCategorysInBlogsPublished failed during the select. There are no BlogCategory entries.'   
  104.                                RAISERROR (@Message, 16, 1)  
  105.                            END    
  106.                    END  
  107.                ELSE  
  108.                    BEGIN  
  109.                         -- Web api access was NOT granted. The user did not have permission to use the web api or there is an error in the GetApiAccess procedure.  
  110.                         -- Pass the message returned from the GetApiAccess procedure.  
  111.                         RAISERROR (@ApiMessageOut, 16, 1 )  
  112.                   END  
  113.           END  
  114.           
  115.        -- Returns success.  
  116.        RETURN 0  
  117.    
  118.     END TRY  
  119.   
  120.     BEGIN CATCH  
  121.         SELECT   
  122.               @ErrorLine = ERROR_LINE()  
  123.               -- ERROR_MESSAGE() contains the RAISERROR message raised above.  
  124.             , @ErrorMessage = ERROR_MESSAGE()  
  125.             , @ErrorNumber = ERROR_NUMBER()  
  126.             , @ErrorSeverity = ERROR_SEVERITY()  
  127.             , @ErrorState = ERROR_STATE()  
  128.             , @DatabaseName = CAST(DB_NAME() AS VARCHAR)  
  129.             , @ServerName = CAST(SERVERPROPERTY ( 'ServerName' ) AS VARCHAR)  
  130.             , @CRLF  = CHAR(13) + CHAR(10)  
  131.       
  132.             SET @ErrorDescription = 'From stored procedure: '  + ERROR_PROCEDURE()   
  133.                                     + '. Error Line: '  + CAST(@ErrorLine AS VARCHAR)  
  134.                                     + '. Error Message: ' + @ErrorMessage  
  135.                                     + ' Error Number: ' + CAST(@ErrorNumber AS VARCHAR)  
  136.                                     + '. Error Severity: ' + CAST(@ErrorSeverity AS VARCHAR)  
  137.                                     + '. Error State: ' + CAST(@ErrorState AS VARCHAR)  
  138.                                     + '. Database Name: '  + @DatabaseName  
  139.                                     + '. Server Name: ' + @ServerName  
  140.   
  141.         IF (XACT_STATE() <> 0)  
  142.             BEGIN  
  143.                ROLLBACK TRANSACTION   
  144.             END  
  145.        
  146.         IF (@ErrorSeverity = 16) AND (@ErrorState = 2)  
  147.             -- If it's a validation error (which we use 16/2 for).  
  148.             BEGIN   
  149.                -- Just send the validation message.  
  150.                RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)  
  151.             END        
  152.         ELSE  
  153.             BEGIN   
  154.                -- Log the critical error.     
  155.                BEGIN TRY  
  156.                   EXEC dbo.InsertBlogErrorLog  
  157.                              @a_LogDateTime = @CurrentDateTime,      
  158.                              @a_UserName = @a_UserName,       
  159.                              @a_UserIpAddress = @a_IpAddress,          
  160.                              @a_ObjectID = @@PROCID,  
  161.                              @a_MessageType = 'S/P Critical Error',  
  162.                              @a_LogMessage = @ErrorDescription             
  163.                END TRY  
  164.   
  165.                BEGIN CATCH  
  166.                   -- Stack the messages.  
  167.                   SELECT @Message = 'Critical Error - procedure InsertBlogErrorLog failed. A log entry cannot be made. Do not continue. Contact IT. Initial error message: ' + @ErrorMessage  
  168.                   RAISERROR(@Message, 16, 1)   
  169.                END CATCH  
  170.   
  171.                SELECT @message = 'Critical Error - do not continue. Contact IT and provide this log date: ' + Convert(VARCHAR, @CurrentDateTime,21)  
  172.                RAISERROR(@Message, 16, 1)                   
  173.             END  
  174.   
  175.          -- Returns failure.  
  176.          RETURN 1        
  177.      
  178.     END CATCH  
  179.     END  
 
 

Answers (4)