简体   繁体   English

在 http API 中对“错误请求”引发异常是否是一种好习惯 - 与(Java)最佳实践相矛盾

[英]Is it good practice to raise an exception on "bad requests" in an http API - in contradiction to (Java) best practice

Normally I try to use exceptions only for "exceptional" conditions ("Effective Java ", Issue 69) .通常,我尝试仅将异常用于“异常”条件(“Effective Java”,第 69 期) My personal interpretation is: if I hit a condition in a specific part in code (normally a method or constructor) where I can't give a meaningful answer or outcome anymore I throw an exception and whoever called the piece of code has to handle it.我个人的解释是:如果我在代码中的特定部分(通常是方法或构造函数)遇到一个条件,我不能再给出有意义的答案或结果,我会抛出一个异常,调用这段代码的人必须处理它.

In the special case of HTTP endpoints I can always give a meaningful answer - a response with a status code.在 HTTP 端点的特殊情况下,我总是可以给出一个有意义的答案 - 带有状态代码的响应。 Handling bad requests thus belongs to normal program flow of endpoint methods and should not raise new exception.因此,处理坏请求属于端点方法的正常程序流程,不应引发新的异常。

Eg an endpoint that returns a resource should just return 404 in case the resource is not found.例如,如果找不到资源,返回资源的端点应该只返回 404。 In my opinion it would be bad practice to raise a "SomethingNotFoundExcetion" (that could be handled by an error handler and create 404 response)在我看来,引发“SomethingNotFoundExcetion”(可以由错误处理程序处理并创建 404 响应)是不好的做法

My question is: It is bad practice to use Spring Boot's error handling mechanism for bad requests (4xy) that relies on exceptions to create specific HTTP responses.我的问题是:对于依赖异常创建特定 HTTP 响应的错误请求 (4xy) 使用 Spring Boot 的错误处理机制是不好的做法。 (It is really fine for all uncovered errors yielding 500) (对于所有未发现的错误产生 500 真的很好)

(I am just writing a review of code and I am not sure if I should suggest to not use error handler for "normal" API interaction) (我只是在写代码审查,我不确定是否应该建议不要将错误处理程序用于“正常”API 交互)

Answer/Comment to current answers对当前答案的回答/评论

It seems that the most of you missed the important part of my reasoning: (citing Effective Java, Item 69):似乎你们中的大多数人都错过了我推理的重要部分:(引用 Effective Java,Item 69):

Use exceptions only for exceptional conditions ...仅在异常情况下使用异常...

this reasoning: • Because exceptions are designed for exceptional circumstances, there is little incentive for JVM implementors to make them as fast as explicit tests.这个推理: • 因为异常是为特殊情况设计的,JVM 实现者几乎没有动力让它们像显式测试一样快。 • Placing code inside a try-catch block inhibits certain optimizations that JVM implementations might otherwise perform. • 将代码放在 try-catch 块中会禁止 JVM 实现可能执行的某些优化。

The main point for me is:我的主要观点是:

A well-designed API must not force its clients to use exceptions for ordinary control flow.设计良好的 API 不得强迫其客户端对普通控制流使用异常。

Especially in case of rest API.特别是在休息 API 的情况下。 It should be easy to use any API in a way to avoid exceptions at all.以完全避免异常的方式使用任何 API 应该很容易。 This means for me.这对我来说意味着。 No correct (defined eg in Open API) usage of a Rest API should raise an exception.没有正确(例如在 Open API 中定义)使用 Rest API 应该引发异常。

To put another point: The standard for SOAP (another http based API stuff) forbids to use "SOAP fault" for correct (defined by WSDL) requests.再说一点:SOAP 标准(另一个基于 http 的 API 内容)禁止对正确(由 WSDL 定义)请求使用“SOAP 错误”。

For me raising exception in remote APIs on not exceptional cases are even worse then in classic API (via dependency).对我来说,在非异常情况下在远程 API 中引发异常比在经典 API 中(通过依赖)更糟糕。

It depends on your project, it's really a matter of opinion/architectural decision.这取决于您的项目,这实际上是意见/架构决定的问题。 I'd say either-or.我会说非此即彼。

The advantage of using specific Exception s and then using a Spring handler to map them is that it removes the tedious construction of responses with the correct code from the actual application logic code (it's not dissimilar from aspects in that respect): just throw the correct exception and be done with it.使用特定的Exception s 然后使用 Spring 处理程序来映射它们的优点是,它从实际的应用程序逻辑代码中删除了带有正确代码的响应的繁琐构造(在这方面与方面没有不同):只需抛出正确的例外并完成它。

OTOH, the distance to the error handling code means that 1. if something doesn't work, it may be difficult to track down the issue 2. you need to know what exceptions to throw, and that is not immediately obvious and needs to be documented well. OTOH,与错误处理代码的距离意味着 1. 如果某些事情不起作用,则可能很难追踪问题 2. 您需要知道要抛出哪些异常,这不是立即显而易见的,需要记录良好。

It is not a bad practice, but a matter of architectural decision.这不是一种糟糕的做法,而是架构决策的问题。 It could be good to have an error handler that will produce a 4xx response and will do some additional error handling work, such as logging, and/or sending a notification by mail or queue or (like in my project) write errors in the table so they could be reviewed by user using GUI component of an application and may be even edited and re-submitted if it makes sense.最好有一个错误处理程序,它会产生 4xx 响应并执行一些额外的错误处理工作,例如记录日志和/或通过邮件或队列发送通知或(如在我的项目中)在表中写入错误因此,用户可以使用应用程序的 GUI 组件对其进行审查,如果有意义,甚至可以对其进行编辑和重新提交。 It also unifies the error handling to a single code (code re-use).它还将错误处理统一为单个代码(代码重用)。 But if you really just need to send a 4xx response and nothing else, then its OK not raise exception and just do it in your code.但是如果你真的只需要发送一个 4xx 响应而不是其他任何东西,那么它不会引发异常并且只需在你的代码中执行它。 Raising exception is expensive performance-wise and shouldn't be done just for the sake of raising exception alone.引发异常在性能方面代价高昂,不应仅仅为了引发异常而这样做。 But in this particular case my opinion is to use Exception/Spring boot Error handling mechanism但在这种特殊情况下,我的意见是使用 Exception/Spring boot 错误处理机制

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

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