【发布时间】:2015-04-28 10:59:18
【问题描述】:
我有一个通过 WCF 进行通信的 C# 应用程序/服务链,以及一个 MVC Web 应用程序,它有时可以沿着这个服务链发起操作。
我想要的是一种安全的方式来报告此链中发生的有用错误,一旦网络应用用户发起导致异常的操作。我当前的解决方案是尽快捕获任何异常,然后使用最能识别导致问题的自定义消息创建一个 CustomException。此 CustomException 将通过 try/catch 块向上传播服务链(使用[FaultContract (typeof(SerialisedCustomException)] 在服务边界处序列化)。当在任何时候捕获到异常时,如果它是 CustomException 类型,它将被重新抛出。否则会像上面一样当场创建一个 CustomException,然后进一步抛出。
作为一个用例,假设登录到我的 Web 应用程序 A 的用户执行了一个操作,告诉服务 B 告诉服务 C 在 C 的文件系统上创建一个文件。 (实际动作比这更复杂,而且不止一件事情可能出错,但我认为这是一个足够的例子)
如果在此过程中出现任何问题,我希望以这样的方式通知用户,以便他可以解决问题。
通过 safe,我只想向用户显示我专门创建的错误(因此我使用了 CustomException),而不是其他任何内容(如果抛出系统异常,比如 UnauthorizedAccessException ,我将把它包装在我自己的 CustomException 中,并且只向最终用户显示我自己的 CustomException 的消息。我不希望向用户显示任何可能暴露实现细节的异常消息。
通过有用,我想向用户显示适当的消息和建议,例如“确保您拥有正确的权限等”,而不是 '服务 B 说:内部服务器错误'。(这些将在第一次抛出 CustomException 时设置,并且不会在进一步捕获/抛出时更改。如果启用调试,我还将显示堆栈跟踪,但在生产中我只会显示我的安全自定义消息)。
我的方法的问题是,我越来越多地围绕我的服务方法编写 try/catch 块,在它们调用的方法中等等,我觉得这不是正确的方法,并且有更好、更高效/不那么臃肿的解决方案。
有什么方法可以解决这个问题,同时避免将所有内容包装在 try/catch 块中的开销吗?
编辑:添加了需要报告错误的理由,而不是说“出了点问题,我们正在调查。”
我的网络应用可以在较低级别的服务上发起复杂的(和可定制的)操作。这些失败的原因有很多,可以通过调整该操作的自定义来解决。
例如,假设我有一个操作将用户输入的源文件复制到用户输入的目标位置(在机器 C 上,或在机器 C 可访问的网络驱动器上)。由于各种原因(未找到文件、网络关闭、缺少权限、磁盘空间不足等),此操作可能会失败,但某些原因可以通过用户更改该自定义操作来解决,前提是他们能够看看为什么它首先失败了。
【问题讨论】:
-
那么所有这些尝试捕获 - 它们中的每一个都会产生一个单独的、对最终用户有意义的错误吗?
-
希望是的。或者如果不是,则尽可能接近初始异常的来源。所以最坏的情况是你会得到一个“无法创建目录 X”而不是“复制操作失败”,例如。
-
我无法摆脱这种感觉,即您正在尝试做的事情比实际做的要多。在这方面,Mehrzad Chehraz 的答案是正确的。如果您有用户可纠正的错误“找不到文件”,那么您需要一个一个地处理它们 - 所以这里没有解决这个问题,但是像“网络关闭”这样的其他错误只是一般性中断。另一个想法是在创建/排队操作之前添加验证检查,以最大程度地减少运行时出错的机会。文件存在吗?用户有权限吗?这种东西
-
而且在您的情况下缺少权限也很可能是“系统错误”而不是用户错误,尤其是当我们谈论文件系统权限时。这不像用户可以更改服务的文件系统权限以访问文件。我猜整个事情需要在更广泛的背景下考虑。您的应用程序到底在做什么以及如何做的?可能是您需要在其他地方更改设计以避免这里出现问题。