简体   繁体   English

使用多个类时,一般处理Try / Catch块和错误的正确方法是什么?

[英]What's the correct way to deal with Try/Catch Blocks and Errors in General when using multiple classes?

I'm trying to understand the correct structures of a program here to facilitate everything. 我试图在这里理解程序的正确结构以促进一切。 Basically where to "put" things. 基本上在哪里“放”东西。

For example: 例如:

You have 2 classes. 你有2个班级。

Class 1 is your main. 1级是你的主力。

Both classes have many methods. 这两个类都有很多方法。

Class 1 calls for an instance of Class 2 and runs a method. Class 1调用Class 2的实例并运行一个方法。 This method is supposed to return a value. 该方法应该返回一个值。

Question 1: Should I have a try/catch block INSIDE this method (in Class 2)? 问题1:我是否应该在此方法中使用try / catch块(在第2类中)?

Question 2: Should the try/catch block be where I call the method (in Class 1)? 问题2:try / catch块应该在我调用方法的地方(在Class 1中)吗?

try
   method();
catch
...

Question 3: When executing the method that is in Class 2, when it comes to returning a value, should I ever return "an error code" and then deal with this code in the calling class? 问题3:当执行类2中的方法时,在返回值时,我是否应该返回“错误代码”然后在调用类中处理此代码?

Question 4: When an error happens and I need to "halt" the program, should I use if/else statements so the code only moves forward if the correct conditions are met or should I use the keyword "break" more often? 问题4:当一个错误发生并且我需要“暂停”程序时,我是否应该使用if / else语句,以便只有在满足正确条件时代码才会向前移动,或者我应该更频繁地使用关键字“break”?

Question 5: The possibilities for errors could be endless, specially if you have medium to large programs. 问题5:错误的可能性可能是无穷无尽的,特别是如果你有大中型程序。 How do you guys deal with unknowable errors which you might encounter while the user is running your program? 你们如何处理用户运行程序时可能遇到的不可知错误?

Exceptions are just that: exceptional. 例外就是:例外。 You shouldn't be using exceptions for regular program flow. 您不应该使用常规程序流的例外。 (If you say, "Oh yeah, I expected that", it probably shouldn't be an exception.) (如果你说,“哦,是的,我期待的那样”,它可能不应该是一个例外。)

Handle the exception where it needs handling. 处理需要处理的异常。 If you can survive the function without that try-catch block succeeding, then you should handle it there. 如果你能在没有try-catch块成功的情况下继续使用该函数,那么你应该在那里处理它。 Similarly, if you need to wrap some things up, you can also add a finally block ( using is similar to finally in C#- it compiles down to try-finally , but is not as robust as writing it yourself. It simply calls .Dispose() on the disposable object you specified). 类似地,如果你需要包装一些东西,你也可以添加一个finally块( using类似于finally在C#中 - 它编译为try-finally ,但不像自己编写那样健壮。它只是调用.Dispose()指定的一次性对象)。

But if you need to bail out of that function, or you're running a string of functions that need to all succeed in your main class, it might be better to do the handling in your Class 1. 但是如果您需要摆脱该功能,或者您正在运行一系列需要在主类中取得成功的函数,那么在类1中进行处理可能会更好。

Caveat: There are exceptions (ha!) to every rule. 警告:每条规则都有例外(哈!)。 As you program more, you can get an intuitive sense of where error handling should be done- but often there will be more than one option and it may not be clear cut. 随着您的编程越来越多,您可以直观地了解应该在哪里进行错误处理 - 但通常会有多个选项,而且可能并不明确。

In general, the answer to all those questions is "it depends". 一般来说,所有这些问题的答案都是“它取决于”。 Clearly what you need to do depends on the specific circumstances of the situation and the application it contains. 显然,您需要做的事情取决于具体情况及其包含的应用程序。

From a practices point of view, I generally follow a couple rules: 从实践的角度来看,我通常遵循一些规则:
1. Use exception handling instead of error codes 1.使用异常处理而不是错误代码
2. Only use try/catch when I know how to handle an exception 2.当我知道如何处理异常时,只使用try / catch

Clearly no one can tell you whether you need a try/catch within a method without knowing what that method does and whether or not you can handle any exceptions. 显然没有人能够告诉你在方法中是否需要try / catch而不知道该方法的作用以及是否可以处理任何异常。

Whether or not an error code is really applicable is up to you. 错误代码是否真的适用取决于您。 I generally view it as not applicable; 我一般认为它不适用; but, sometimes it might be. 但是,有时它可能会。 In those cases I only view it as applicable if the caller will always use the code and not pass it on. 在这些情况下,如果调用者始终使用代码而不传递代码,我只会将其视为适用。 "GetErrorCode" might be a good example of a case where an error code may be applicable. “GetErrorCode”可能是错误代码可能适用的一个很好的例子。

You can't possibly "handle" (ie compensate for) "unknown" errors. 你不可能“处理”(即补偿)“未知”错误。 The recommended practice is the not handle the exception and let the handle terminate gracefully because it's in an unknown state. 建议的做法是不处理异常并让句柄正常终止,因为它处于未知状态。

I in general agree w/ David and Peter... The one thing I would add is to be careful about exceptions you catch when you catch them... Richter has a very interesting chapter on exception handling and how exceptions were SUPPOSED to be inherited versus how they have actually been implemented... But even still, it's (IMO) lazy or at least ill-thought-out if you find yourself consistently catching the generic Exception class... 我总体上同意大卫和彼得......我要补充的一件事就是要小心你抓到它们时遇到的异常...... 里希特有一个关于异常处理的非常有趣的章节,以及如何继承异常被支持与他们实际实现的方式相比......但即使如此,如果你发现自己一直在捕捉通用的Exception类,那么(IMO)是懒惰的,或者至少是经过深思熟虑......

If you're doing file reading/writing, you may very well want to catch appropriate IO exceptions, but to consistently catch the most generic Exception class can lead you to problems if say, a NullReferenceException gets thrown and your try/catch was only protecting against IO Exceptions... Your catch block would try to fix (what it assumed was) an IO exception and it could put your code in a horribly unstable state. 如果你正在进行文件读/写,你很可能想要捕获适当的IO异常,但是为了始终捕获最通用的异常类会导致你遇到问题,如果抛出NullReferenceException并且你的try / catch只是保护针对IO Exceptions ...你的catch块会尝试修复(它假设的)一个IO异常,它可能会使你的代码处于一个非常不稳定的状态。

Additionally, be very careful about continuing to re-throw the original error unless you're convinced you TRULY handled it appropriately... If you wrote a library and published it and swallowed all the errors because you thought you were doing the best thing, then someone that consumed your library would have no way to debug what was going on... Exceptions also get thrown into the servers logs, so a swallowed error would never make it there. 另外,要非常小心继续重新抛出原始错误,除非你确信你正确处理它...如果你写了一个库并发布它并吞下所有错误,因为你认为你做的最好,那么消耗你的库的人将无法调试正在发生的事情......异常也会被抛入服务器日志中,因此吞下的错误永远不会让它存在。

The one place that I would advocate catching the generic error is right at the UI layer where you obviously don't want to show the user a YSOD, but even then your catch should likely do some logging or something to help you debug later. 我主张捕获泛型错误的一个地方是在UI层,你显然不希望向用户显示YSOD,但即便如此,你的捕获应该可能会做一些日志记录或某些东西来帮助你稍后调试。

Catching exceptions and returning error codes/bools leads to "arrow" code like so: 捕获异常并返回错误代码/ bool导致“箭头”代码如下:

if(Func1())
{
   if (Func2())
   {
       if (Func3())
       {
       }
   }
}

I unfortunately maintain a complex project where exceptions are treated like Ebola and are contained as soon as they sprout up. 遗憾的是,我维持了一个复杂的项目,其中异常被视为埃博拉病毒,并且一旦发芽就被包含在内。 It really just makes the code harder to understand and maintain. 它实际上只是使代码更难理解和维护。

It depends on how you visualize and structure your application. 这取决于您如何可视化和构建应用程序。 Are classes 1 & 2 part of the same module or are they in different modules? 1类和2类是同一模块的一部分还是属于不同的模块? In general, a module provides "API" and the caller of the "API" needs to catch errors and exceptions. 通常,模块提供“API”,“API”的调用者需要捕获错误和异常。 Have a look at Defensive Programming . 看看防守编程

Question 1: Should I have a try/catch block INSIDE this method (in Class 2)? 问题1:我是否应该在此方法中使用try / catch块(在第2类中)?

If Class 2 is a separate module and you do not want to propagate the exceptions to the caller module, then yes. 如果Class 2是一个单独的模块,并且您不希望将异常传播给调用者模块,那么是。 If you want to, then no. 如果你愿意,那么没有。 The exceptions thrown from this Class/Module then need to be documented. 然后需要记录从此类/模块抛出的异常。

If Class 1 & 2 are in same module, then again it depends if you want to handle the exceptions within the internal classes or not. 如果类1和2在同一个模块中,那么它又取决于您是否要在内部类中处理异常。

Question 2: Should the try/catch block be where I call the method (in Class 1)? 问题2:try / catch块应该在我调用方法的地方(在Class 1中)吗?

If you want to safeguard to ensure Class 1 does not throw further exceptions, then yes. 如果您想保护以确保第1类不会引发进一步的例外,那么是。

Question 3: When executing the method that is in Class 2, when it comes to returning a value, should I ever return "an error code" and then deal with this code in the calling class? 问题3:当执行类2中的方法时,在返回值时,我是否应该返回“错误代码”然后在调用类中处理此代码?

If you want to throw exception of return an error code, is again a design/implementation decision. 如果要抛出异常返回错误代码,则再次是设计/实现决策。

Question 4: When an error happens and I need to "halt" the program, should I use if/else statements so the code only moves forward if the correct conditions are met or should I use the keyword "break" more often? 问题4:当一个错误发生并且我需要“暂停”程序时,我是否应该使用if / else语句,以便只有在满足正确条件时代码才会向前移动,或者我应该更频繁地使用关键字“break”?

To use break you will need a loop in the caller. 要使用break,您需要在调用者中使用循环。

Question 5: The possibilities for errors could be endless, specially if you have medium to large programs. 问题5:错误的可能性可能是无穷无尽的,特别是如果你有大中型程序。 How do you guys deal with unknowable errors which you might encounter while the user is running your program? 你们如何处理用户运行程序时可能遇到的不可知错误?

Large programs are divided into modules and could be coded by different developers. 大型程序分为模块,可由不同的开发人员编写。 So the design and interface contract becomes essential here. 因此,设计和界面合同在这里变得至关重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM