.NET当内部函数引发异常时如何从外部函数退出

时间:2018-05-02 15:49:51

标签: c# .net exception-handling

我很难在一段代码中正确控制流量。我有一个函数GetVoucherNumberAndApplyToDatabase(),它调用一个单独的函数doPatientEncounterCreate()。如果内部函数抛出异常,我希望外部函数停止它在那里做的事情,因为它取决于返回的返回值。

以下是一些清晰的代码:

    //outer function
    private int GetVoucherNumberAndApplyToDatabase(int Mode)
    {
        int ProviderID = 0;
        int PracticeMRNumber = 0;
        int VoucherNumber = 0;
        string EncounterD = DateTime.Now.ToString("MM\\/dd\\/yyyy");
        try
        {
            EncounterCreateResults = doPatientEncounterCreate(practiceID, PracticeMRNumber, ProviderID, ddlVisitType.SelectedValue, EncounterD);

            /*
            if (EncounterCreateResults.ErrorMessage.Length > 0)
            {
                throw Exception;
            }
            */

            ...

            //fails bc doPatientEncounterCreate threw exception
            ApplyVoucherNumberToBillingCharges(practiceID, ReasonCodeID);
        }
        catch (ReasonCodeException ex)
        {
            pnlError.Visible = true;
            lblErrorMessage.Text = ex.Message;
        }
        catch (Exception ex)
        {
            pnlError.Visible = true;
            lblErrorMessage.Text = "An error occurred attempting to call the API: " + ex.Message;  
        }

    }

    //inner function
    public static EncounterResults doPatientEncounterCreate(int PracticeID, int PatientID
                                                  , int ProviderID, string ReasonCodeID, string EncounterD)
    {
        try
        {
            DataTable ReasonCodeDT = getSingleReasonCode(PracticeID, ReasonCodeID);

            string strReasonCode = String.Empty;
            string strReasonDescription = String.Empty;
            string strDuration = String.Empty;
            string strActive = String.Empty;

            if (ReasonCodeDT.Rows.Count != 1)
            {
                string strPracticeID = PracticeID.ToString();
                string PracticeName = getSingleStringResultFromSQL("SELECT @result ...); 
                string RecordCount = ReasonCodeDT.Rows.Count.ToString();
                throw new ReasonCodeException("Database Returned " + RecordCount + " Records for ReasonCodeID " + ReasonCodeID + " for Practice " + PracticeName + " (" + strPracticeID + ")");
            }
            else
            {
                DataRow Row = ReasonCodeDT.Rows[0];
                strReasonCode = Row["ReasonCodeID"].ToString();
                strReasonDescription = Row["Description"].ToString();
                strDuration = Row["Duration"].ToString();
                strActive = Row["Active"].ToString().ToLower();
            }

            string strReasonID = @"""ReasonCode"": {""Code"": """ + strReasonCode + @""", ""Description"":""" + strReasonDescription + @"""" +
                                @", ""Duration"": " + strDuration + @", ""Active"": " + strActive + @"}, ";
        }
        /*
        catch (ReasonCodeException ex)
        {
            Results.ErrorMessage = ex.Message;
            return Results;
        }*/
        catch (Exception ex)
        {
            ErrorLog.LogError(ex, "doPatientEncounterCreate Failed.", Convert.ToInt32(au.UserID), "");
            Results.ErrorMessage = ex.ToString();
            return Results;
        }
    }

    //Custom Exception Class used in doPatientEncounterCreate
    class ReasonCodeException : Exception
    {
        public ReasonCodeException()
        {

        }

        public ReasonCodeException(string Message):
            base ()
        {
            ErrorLog.LogError(Message);
        }

    }

我已经接受了这个问题的第二个答案的建议:Exit all functions from code in inner function

但是,即使我已将ReasonCodeException catch块移动到外部函数,但在运行代码时,内部函数doPatientEncounterCreate()中会抛出一般异常,然后代码继续oter函数,直到抛出异常,因为它缺少从内部函数返回的值。

另外,我不能按照上面问题的接受答案的建议,因为内部函数不是void函数,我需要返回的值。

非常感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:2)

对于您要完成的任务,您可以接受doPatientEncounterCreate方法中的try catch块吗?

这将允许GetVoucherNumberAndApplyToDatabase方法中的try catch块捕获doPatientEncounterCreate中发生的任何异常。

如果你需要在内部方法中使用try catch块,然后在注释中建议binDebug,那么在catch块中执行你需要的操作然后重新抛出以便你的外部方法捕获是有意义的它

为了澄清“重新抛出”的含义,这里是对example的引用。而且,这是一个简短的代码示例:

catch(Exception e)
{
    // do something
    throw;
}

答案 1 :(得分:0)

现在,您已注释掉特定的异常捕获并仅处理通用异常(它还捕获了特定的异常)。

现在您不会抛出异常而只返回有效的响应。

根据您的需要,您可以通过记录等处理任何特定异常作为子级中的正确逻辑链,然后进行重新抛出。 请注意,有2种重新抛出机制," throw"和"抛出前"。在这里,您需要执行throw,因为它将保留堆栈跟踪而不会创建嵌套的内部异常。

另一种方法是不处理内部函数中的任何异常,并让更高级别的函数进行处理,通常是在管道级别。 理想情况下,所有已知的异常都应该在发生时处理,任何未知的异常都应该在全球顶级处理