简体   繁体   English

Try Catch 块后抛出异常

[英]Throw Exception after Try Catch block

I'm consuming an external SOAP service in my Spring app.我正在我的 Spring 应用程序中使用外部 SOAP 服务。 The SOAP service can throw an Exception while connecting so I catch that in a try catch block: SOAP 服务可以在连接时抛出异常,所以我在 try catch 块中捕获它:

try {
    response = soapService.callService(request);
} catch (Exception e){
    throw SoapServiceException("explaining",e);
}

if (BAD_STATUS_CODE.equals(response.getStatusCode()) {
    throw CustomException("explaining", e);
}

return response;

As you can notice, I also want to throw an exception when response is not what caller would expect, maybe for example because valid request format but values not found in soap service.如您所见,当响应不是调用者所期望的时,我还想抛出异常,例如,可能是因为有效的请求格式但在 soap 服务中找不到值。

Is this a good practice?这是一个好习惯吗? I'm trying to prevent wrapping the response object in another object that keep the error codes.我试图防止将响应 object 包装在另一个保留错误代码的 object 中。 I think it would be nice if service caller handles the exceptional cases like soap exception or the response exception.我认为如果服务调用者处理 soap 异常或响应异常等异常情况会很好。 Thanks for your advice.谢谢你的建议。

Exception are a feature of the java programming language but are not mandatory to be used.例外是 java 编程语言的一个特性,但不是必须使用的。 Well you may have to catch the existing ones, but you don't have to raise new one.好吧,您可能必须抓住现有的,但您不必提出新的。

This is a design decision for your application/framework/library.这是您的应用程序/框架/库的设计决策。 It is much better if the way to handle error in general is consistant accross the whole codebase.如果处理错误的方式在整个代码库中通常是一致的,那就更好了。 There isn't a better, universal way.没有更好的通用方法。 It is a collective choice and also depend of the general expected behavior of your program.这是一个集体选择,也取决于您的程序的一般预期行为。

A simple design一个简单的设计

A "naive" or at least simple implementation typically would raise exception for many unsupported cases as this is an easy way to interrupt the execution, get a log of the error and an easy way to investigate.对于许多不受支持的情况,“幼稚”或至少简单的实现通常会引发异常,因为这是中断执行、获取错误日志和调查的简单方法。

In that way of seeing things, it isn't necessarily worth to have checked exception.以这种方式看待事物,不一定值得检查异常。 Your exceptions can derive from RuntimeException, you don't need to declare them and simply raise them when there an issue.您的异常可以从 RuntimeException 派生,您无需声明它们并在出现问题时简单地提出它们。

The drawback of such design is that developpers will likely raise exception in many cases and that most these "exceptional" cases are actually common case in your application.这种设计的缺点是开发人员可能会在许多情况下引发异常,并且大多数这些“异常”情况实际上是您的应用程序中的常见情况。 A file is not found?找不到文件? Well that's common.嗯,这很常见。 The network isn't available?网络不可用? That's to be expected.这是可以预料的。 The service didn't return what you do expect?该服务没有返回您所期望的? That can happen more often than you think...这可能比你想象的更频繁地发生......

At least in our production where we have thing like thousand of machines and hundred thousand of TPS everything will happen.至少在我们拥有数千台机器和数十万 TPS 的生产中,一切都会发生。

Toward a more robust implementation迈向更强大的实施

So typically you'll separate what you'll consider to be something that you expect to happen and have to deal with (like a timeout for a network request or the DB being temporarilly unvalaible) or what shall never happen (a file part of your artifact distribution missing) or invalid parameters provided to a function (a code bug).因此,通常您会将您认为会发生并且必须处理的事情(例如网络请求的超时或数据库暂时不可用)或永远不会发生的事情(文件的一部分)分开工件分布缺失)或提供给 function 的参数无效(代码错误)。

You'll keep exception for what is truely exceptionnal, and typically make them RuntimeException/unchecked because there nothing to be done.您将保留真正异常的异常,并且通常将它们设为 RuntimeException/unchecked,因为没有什么可做的。 You just want such bugs to be logged and repported.您只希望记录和报告此类错误。

For all the rest, there may be exception in the middle but not globally.对于所有的rest,中间可能有例外,但不是全局的。 You want to deal with them and consider them as normal behavior.您想处理它们并将它们视为正常行为。

In that case, the choice is your depending of the design.在这种情况下,选择取决于您的设计。

But typically if I have to act and proceed normally when that occurs, I prefer as well to not have an exception.但通常情况下,如果我必须在发生这种情况时正常采取行动并继续进行,我也希望没有例外。 Typically for a network request, I would consider the Time Out to be actually be a valid response and returned as this to be part of the values I model in my business domain.通常对于网络请求,我会认为超时实际上是一个有效的响应,并作为我的业务域中值 I model 的一部分返回。

To have the Error and errors code part of my data domain allow me to accumulate/aggregate errors and to fine tune how I react to them.让我的数据域中的错误和错误代码部分允许我累积/聚合错误并微调我对它们的反应方式。 An exception on the opposite is more an all or nothing.相反的例外是全有或全无。

This allows for more flexibility on how functionnally I choose to react... Like I performed 10 requests, one time out, on returned an error, I don't want exceptions.这让我在选择如何在功能上做出反应时具有更大的灵活性......就像我执行了 10 个请求,一次超时,返回一个错误,我不想要异常。 I want the results and a "merge" strategy that depend of the functional aspects of my application.我想要取决于我的应用程序功能方面的结果和“合并”策略。

In your example of BadStatus, I would consider it as an exception if that 's an error code I get because I provided invalid inputs (a bug in my code).在您的 BadStatus 示例中,如果这是我得到的错误代码,我会将其视为异常,因为我提供了无效的输入(我的代码中的错误)。 But if that's because there no network or because there was an external failure, that expected behavior for me, so I would not throw.但如果那是因为没有网络或因为有外部故障,那对我来说是预期的行为,所以我不会扔。

That's my design choice, that's the teams I have been working with design choice.那是我的设计选择,那是我一直与设计选择合作的团队。 This doesn't has to be the universal choice.这不一定是普遍的选择。 Just be sure you all agree on how to deal with such case and it match your overall software design只要确保你们都同意如何处理这种情况,并且它与您的整体软件设计相匹配

Checked exceptions已检查的异常

They force you do deal with it, and this can be a bless or a curse depending of the context.他们强迫你处理它,这可能是一种祝福或诅咒,具体取决于上下文。

This is a choice that you have in your design.这是您在设计中的选择。

Do you only throw exception in exceptional cases that should not happen and use it as bug detection mechanism?您是否只在不应发生的异常情况下抛出异常并将其用作错误检测机制? Then I think they are useless and when I use this strategy I wrap them in a derivate of RuntimeException to simplify my code and in a few key areas of my code I have generic catch all mechanisms that can be seen as framework lvl so I ensure I always return a proper response (even if that one with an error) and then I can centralize the loggging.然后我认为它们没用,当我使用这种策略时,我将它们包装在 RuntimeException 的派生中以简化我的代码,并且在我的代码的几个关键区域中,我有通用的 catch 所有可以被视为框架 lvl 的机制,所以我确保我总是返回一个正确的响应(即使那个有错误),然后我可以集中记录日志。

But again if you think the client shall alway deal with it, use the checked exception.但同样,如果您认为客户端应该始终处理它,请使用已检查异常。 The problem with that is that most often the caller cannot do anything directly, he may need to wrap into many intermediate just to forward it or have an handless list of checked exceptions.这样做的问题是,大多数情况下调用者不能直接做任何事情,他可能需要包装到许多中间来转发它或拥有一个已检查异常的无句柄列表。

So I am not that fond of them.所以我不是很喜欢他们。 But again that a design decision for you and the team.但对于您和团队来说,这又是一个设计决定。

Throwing exceptions in your code when the behaviour is unexpected is absolutely fine.当行为出乎意料时,在代码中抛出异常绝对没问题。 Just be sure to mark your method请务必标记您的方法

void testMethod() throws CustomException, CustomException2, ..

so that the caller of the method knows that there is a chance that an exception can be thrown.这样方法的调用者就知道有可能抛出异常。 Uncaught exceptions will cause your program to terminate so be sure to catch, and handle appropriately.未捕获的异常将导致您的程序终止,因此请务必捕获并正确处理。

[HttpDelete]
        [Route("api/employee/delete")]
        public void Delete(int Id)
        {
            using (EmployeeDBEntities db = new EmployeeDBEntities())
            {
                try
                {
                    Employee emp = db.Employees.FirstOrDefault(e => e.EmpId == Id);
                    db.Employees.Remove(emp);
                    db.SaveChanges();
                }
                catch (Exception ex)
                {
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)
                    {
                        Content = new StringContent(ex.Message)
                    });
                }
            }
        }

In all projects that I've been working we used exactlly as you, we throw an exception instead of wrapp this in any response object.在我一直在工作的所有项目中,我们都像您一样使用,我们抛出异常而不是在任何响应 object 中包装它。 Looks good for me.对我来说看起来不错。

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

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