远程方法的异常
远程方法异常的最佳实践是什么?
我确信您需要在远程方法实现级别处理所有异常,因为您需要将其记录在服务器端。 但之后你应该做什么?
您是否应该将异常包装在 RemoteException (java) 中并将其抛出给客户端? 这意味着客户端必须导入所有可能抛出的异常。 抛出一个包含更少细节的新自定义异常会更好吗? 因为客户不需要知道问题的所有细节。 客户端应该登录什么? 我什至听说过使用返回码(也许是为了提高效率?)来告诉调用者发生了什么。
要记住的重要一点是,必须告知客户出了什么问题。 笼统的回答“出现问题”或根本没有通知是不可接受的。 那么运行时(未经检查的)异常又如何呢?
What are the best practices for exceptions over remote methods?
I'm sure that you need to handle all exceptions at the level of a remote method implementation, because you need to log it on the server side. But what should you do afterwards?
Should you wrap the exception in a RemoteException (java) and throw it to the client? This would mean that the client would have to import all exceptions that could be thrown. Would it be better to throw a new custom exception with fewer details? Because the client won't need to know all the details of what went wrong. What should you log on the client? I've even heard of using return codes(for efficiency maybe?) to tell the caller about what happened.
The important thing to keep in mind, is that the client must be informed of what went wrong. A generic answer of "Something failed" or no notification at all is unacceptable. And what about runtime (unchecked) exceptions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您似乎希望能够区分故障是由于系统故障(例如服务或机器停机)还是业务逻辑故障(例如用户不存在)造成的。
我建议使用您自己的自定义异常包装 RMI 调用中的所有系统异常。 您仍然可以通过将异常传递给自定义异常作为原因来维护异常中的信息(这在 Java 中是可能的,不确定其他语言是否如此)。 这样客户端只需要知道如何处理导致系统故障的一个异常即可。 是否检查此自定义异常或运行时尚有争议(可能取决于您的项目标准)。 我肯定会记录这种类型的失败。
业务类型故障可以表示为单独的异常或某种类型的默认(或空)响应对象。 我会尝试从此类故障中恢复(即采取一些替代操作),并且仅在恢复失败时才进行记录。
It seems like you want to be able to differentiate if the failure was due to a system failure (e.g. a service or machine is down) or a business logic failure (e.g. the user does not exist).
I'd recommend wrapping all system exceptions from the RMI call with your own custom exception. You can still maintain the information in the exception by passing it to your custom exception as the cause (this is possible in Java, not sure about other languages). That way client only need to know how to handle the one exception in the cause of system failure. Whether this custom exception is checked or runtime is up for debate (probably depends on your project standards). I would definitely log this type of failure.
Business type failures can be represented as either a separate exception or some type of default (or null) response object. I would attempt to recover (i.e. take some alternative action) from this type of failure and log only if the recovery fails.
在过去的项目中,我们会在层的最顶层捕获所有服务层异常,通过 DTO/VO 将应用程序特定的错误代码/信息传递到 UI。 这是一种简单的方法,因为每个服务的所有错误处理都在同一位置发生,而不是分散在服务和 UI 层中,这是一种既定的模式。
然后,UI 所要做的就是检查 DTO/VO 中的标志(hasError?)并显示错误消息,它不必知道也不必关心实际的异常是什么。
In past projects we'd catch all service layer (tier) exceptions at the very top of the layer, passing the application specific error codes/information to the UI via DTO's/VO's. It's a simple approach in that there's an established pattern of all error handling happening in the same place for each service instead of scattered about the service and UI layers.
Then all the UI has to do is inspect the DTO/VO for a flag (hasError?) and display the error message(s), it doesn't have to know nor care what the actual exception was.
我总是会在我的应用程序中记录异常(在您问题中定义的服务器端)。
然后我会抛出一个异常,由客户端捕获。 如果调用者可以采取纠正措施来防止异常,那么我将确保异常包含此信息(例如,
DateTime argName 不得是过去的
)。 如果错误是由第三方系统的某些中断引起的,那么我可能会将此信息通过调用堆栈传递给调用者。然而,如果异常本质上是由我的系统中的错误引起的,那么我将构建我的异常处理,以便使用非信息性异常消息(例如
一般失败
)。I would always log the exception within my application (at the server side as defined in your question).
I would then throw an exception, to be caught by the client. If the caller could take corrective action to prevent the exception then I would ensure that the exception contained this information (e.g.
DateTime argName must not be in the past
). If the error was caused by some outage of a third party system then I might pass this information up the call stack to the caller.If, however, the exception was essentially caused by a bug in my system then I would structure my exception handling such that a non-informative exception message (e.g.
General failure
) was used.这就是我所做的。 每个远程方法实现都会捕获服务器端的所有异常并记录它们。 然后它们被包装在自定义异常中,其中将包含问题的描述。 该描述必须对客户端有用,因此它不会包含捕获的异常的所有详细信息,因为客户端不需要它们。 他们已经登录到服务器端。 现在,在客户端,可以按照用户希望的方式处理这些异常。
为什么我选择使用异常而不是返回代码是因为返回代码的一个非常重要的缺点:你不能不费点力气就将它们扔到更高的级别。 这意味着您必须在调用后立即检查错误并在那里进行处理。 但这可能不是我想要的。
Here's what I did. Every Remote Method implementation catches all Exceptions on the server side and logs them. Then they are wrapped in a Custom Exception, which will contain a description of the problem. This description must be useful to the client, so it won't contain all the details of the caught Exception, because the client doesn't need them. They have already been logged on the server side. Now, on the client, these Exceptions can be handled how the user wishes.
Why I chose using Exceptions and not return codes is because of one very important drawback of return codes: you can't throw them to higher levels without some effort. This means you have to check for an error right after the call and handle it there. But this may not be what I want.