我有一些代码为用户提供用户ID,然后向该用户发送电子邮件。

emailUtil.sendEmail(userId, "foo");

public void sendEmail(String userId, String message) throws MailException {
    /* ... logic that could throw a MailException */
}

可能由于多种原因抛出MailException ,电子邮件地址出现问题,邮件模板出现问题等。

我的问题是这样的:你是为这些异常中的每一个创建一个新的异常类型然后单独处理它们还是创建一个MailException然后将一些东西存储在允许的异常(计算机可读的东西,而不是描述文本)中我们根据实际发生的事情做不同的事情。

编辑:作为澄清,例外不是日志和什么不是,这与代码如何对它们做出反应有关。 为了继续使用邮件示例,让我们说当我们发送邮件时,它可能会因为您没有电子邮件地址而失败,或者因为您没有有效的电子邮件地址,或者它可能会失败等等。

我的代码希望对每个问题做出不同的反应(主要是通过更改返回给客户端的消息,但也包括实际逻辑)。

最好是针对这些问题中的每一个进行异常实现,还是一个具有内部特征的伞状异常(一个枚举说),让代码区分它是什么类型的问题。

===============>>#1 票数:10

在我的代码中,我发现MOST异常渗透到UI层,在那里它们被我的异常处理程序捕获,它只是向用户显示消息(并写入日志)。 毕竟,这是一个意想不到的例外。

有时,我确实希望捕获一个特定的异常(正如您似乎想要做的那样)。 但是,您可能会发现这种情况有点罕见,并且它表明使用异常来控制逻辑 - 效率低(慢)且经常不赞成。

因此,使用您的示例,如果您想在未配置电子邮件服务器时运行某些特殊逻辑,您可能需要向emailUtil对象添加一个方法,如:

public bool isEmailConfigured()

...首先调用它,而不是寻找特定的异常。

当发生异常时,它实际上意味着情况完全出乎意料并且代码无法处理它 - 因此您可以做的最好的事情是将其报告给用户(或将其写入日志或重新启动)

至于具有异常层次结构与其中的异常错误代码,我通常会执行后者。 如果您只需要定义新的错误常量而不是全新的类,则更容易添加新的异常。 但是,只要您尝试在整个项目中保持一致,这并不重要。

===============>>#2 票数:8 已采纳

我通常从一般异常开始,并根据需要对其进行子类化。 如果需要,我总是可以捕获一般异常(以及所有子类异常),但也具体。

Java-API的一个示例是IOException,它具有类似FileNotFoundException或EOFException(以及更多)的子类。

这样你就可以获得两者的优点,你没有像以下那样的throw-clauses:

throws SpecificException1, SpecificException2, SpecificException3 ...

将军

throws GeneralException

足够。 但是,如果您想对特殊情况做出特殊反应,您可以随时捕获特定的异常。

===============>>#3 票数:2

@ Chris.Lively

您知道可以在异常中传递消息,甚至可以传递“状态代码”。 你在这里重新发明轮子。

===============>>#4 票数:2

我发现如果你需要根据返回的异常让CODE决定做什么,那么创建一个名为exception的异常子类化公共基类型。 传递的信息应该被视为“只有人眼”而且太脆弱而无法做出决定。 让编译器完成工作!

如果需要通过不知道已检查异常的机制将其传递给更高层,则可以将其包装在RuntimeException(MailDomainException)的合适命名子类中,该子类可以被捕获,并且原始原因可以作用。

===============>>#5 票数:1

这取决于您的应用程序正在做什么。 您可能希望在类似的情况下抛出个别异常

  • 该应用程序是高可用性
  • 发送电子邮件尤为重要
  • 应用程序的范围很小,发送电子邮件是其中很大一部分
  • 应用程序将部署到远程站点,您只能获取调试日志
  • 您可以从mailException中封装的异常的某些子集中恢复,但不能从其他异常中恢复

在大多数情况下,我会说只记录异常的文本,并且不要浪费你的时间来细化已经非常精细的异常。

===============>>#6 票数:1

我倾向于从可能执行问题的方法返回状态对象列表,而不是使用异常。 状态对象包含严重性枚举(信息,警告,错误,...)状态对象名称,如“电子邮件地址”和用户可读消息,如“格式错误的电子邮件地址”

然后,调用代码将决定过滤到哪个UI以及自己处理哪个。

就个人而言,我认为当你无法实现正常的代码解决方案时,例外是严格的。 性能损失和处理限制对我来说有点太多了。

使用状态对象列表的另一个原因是识别多个错误(例如在验证期间)更容易。 毕竟,您只能抛出一个必须在继续之前处理的异常。

想象一下,用户提交的电子邮件的目的地址格式错误,并且包含您要阻止的语言。 您是否抛出了格式错误的电子邮件异常,然后,在他们修复并重新提交后,抛出一个错误的语言异常? 从用户体验的角度来看,同时处理所有这些问题是一种更好的方法。

更新:结合答案

@Jonathan:我的观点是,我可以评估该操作,在这种情况下发送电子邮件,并发回多个失败原因。 例如,“错误的电子邮件地址”,“空白邮件标题”等。

除了一个例外,您仅限于渗透一个问题,然后要求用户重新提交,以便他们发现第二个问题。 这是非常糟糕的UI设计。

重新发明轮子......可能。 但是,大多数应用程序应分析整个事务,以便为用户提供最佳信息。 想象一下,如果你的编译器在第一个错误时停止了死机。 然后修复错误并再次点击编译,让它再次停止以获得不同的错误。 屁股上有多痛苦。 对我来说,这正是抛出异常的问题,因此我说使用不同机制的原因。

===============>>#7 票数:1

我认为上述的组合会给你最好的结果。

您可以根据问题抛出不同的异常。 例如,缺少电子邮件地址= ArgumentException。

但是在UI层中,您可以检查异常类型,如果需要,还可以检查消息,然后向用户显示相应的消息。 如果抛出某种类型的异常(我的应用程序中的UserException),我个人倾向于仅向用户显示信息性消息。 当然,您应该尽可能地在堆栈中进行擦除和验证用户输入,以确保在真正不太可能的情况下生成任何异常,而不是作为可以使用正则表达式轻松检查的格式错误的电子邮件的过滤器。

我也不担心从用户输入中捕获异常的性能影响。 您唯一能够从异常中看到性能问题的时候是它们被抛出并陷入循环或类似情况。

===============>>#8 票数:0

我倾向于使用更少的异常类型,尽管它不是真正的OO方式。 相反,我把一个枚举放到我的自定义异常,它将异常分类。 大多数情况下,我有一个自定义基础异常,它保留了几个成员,可以在派生的异常类型中覆盖或自定义。

几个月前,我在博客中谈到了如何使例外国际化的想法。 它包括上面提到的一些想法。

===============>>#9 票数:0

虽然您可以区分代码执行,但查看异常并不重要,如果它是由“catch exceptionType hierarchy mode”或“if(...)else ... exception code mode”完成的

但是如果你正在开发其他人会使用的软件,比如一个库,我认为创建你自己的异常类型是有用的,可以注意到其他人你的软件可以抛出除正常之外的其他异常,并且它们更好地捕获并且解决他们。

当我使用一个库并且他们的方法只是启动一个'异常'我总是想知道:什么可以导致这个异常?,我的程序必须如何反应?,如果有一个javadoc可能会解释原因,但必须有时间不是javadoc或没有解释异常。 使用WellChossenExceptionTypeName可以避免过多的开销

===============>>#10 票数:0

这取决于捕获异常的代码是否需要区分异常,或者您是否只是使用异常来失败到错误页面。 如果需要在调用堆栈中区分NullReference异常和自定义MailException,请花时间并编写它。 但是大多数时候程序员只是使用异常来捕获所有在网页上抛出错误。 在这种情况下,您只是在浪费精力编写新的异常。

===============>>#11 票数:-1

我会过去的

throw new exception("WhatCausedIt")

如果你想处理你的异常,你可以传递代码而不是“WhatCausedIt”,然后用switch语句对不同的答案做出反应。

  ask by SCdF translate from so

未解决问题?本站智能推荐:

3回复

是否有任何开放源码项目都实现了相同的功能,有无例外?

我正在研究关于使用异常对代码复杂性的影响的论文。 如果我有几千个LOC,它们使用良好的旧错误处理和相同功能的异常,那将是非常不错的。 我什至不知道从哪里开始搜寻。 任何C#,Java,C ++,D项目都足够。 我最好的猜测是在给定版本中切换到异常的项目。 任何帮助表示赞赏。
4回复

我应该从我的服务中抛出可重复的例外吗?

我的服务是DService,我是服务链中的第四个链接,即呼叫流程是在线用户 - > AService - > BService - > CService - > DService - > EService。 当我从DService调用EService时,它会抛
1回复

我们如何针对同一例外情况提供不同的海关消息

自从第一次处理此方案以来,要求了解哪种方法最好。 在这里,对于所有DataIntegrityViolationException ,发送相同的错误消息 对于相同的例外情况,我们如何提供不同的海关消息。 我们需要检查消息字符串吗? 这里在DataIntegrityViolat
2回复

Moby Dick的例外情况

有多种问题( 1 , 2 , 3 , 4等等等等)被称为“为什么不是这个异常捕获”。 可悲的是,这些解决方案都不适合我......所以我遇到了一个真正无法捕获的异常。 我有一段代码(.NET 4.0)检查大文本文件的数字和数字。 测试时我遇到了运行时异常: 你在这里看到的是一个
4回复

从不捕获的例外情况

我知道有些异常类型无法在catch块中捕获,例如.NET 2.0中的StackOverflowException 。 我想知道哪些其他例外不适合捕获,或者与不良做法有关。 我想使用这个异常类型列表的方法是每次在catch块中使用Exception时检查它: 编辑 我认为我没
6回复

处理不可预见的例外情况

如果我想写入文件并处理IOExceptions (如果文件被写保护),我会执行以下操作: 如果我收到意外的异常我的程序将崩溃,用户将报告错误,我将修复它。 这就是我想要的。 所以我应该添加另一个像: 这会有什么不同,最佳做法是什么?
1回复

例外情况下正确工作

例如,我有以下方法: 因此,方法可能会引发2个异常-当根本不存在使用此类参数的会议或会议时间超过当前时间(应该是过去的时间或当前时间)时。 现在,我正在编写单元测试。 简单方法: 当然,带有某些参数的呼叫单元测试将失败。 我想抓住这些情况,因此测试应该成功。 我可以通
6回复

捕获预期的例外情况

我有代码看起来像这样,因为我检查某些数据是否是图像的唯一可靠方法是实际尝试加载它像图像一样。 哪个看起来很糟糕! 处理这些情况的好方法是什么? 你基本上被迫使用if语句之类的异常?
3回复

关于修改集合的例外情况

这个问题已经在这里有了答案: 消费时如何将项目添加到集合中? 11个答案 我有以下代码遍历字典,如果键没有值,它将检查另一个字典中的值并为其分配值。 我一直收到以下异常。 - $exception {"Collection was modified; enu
6回复

缺少数据的例外情况

我想知道丢失数据应该抛出什么样的异常。 例如,如果xml节点不包含数据。 “ 抛出新的异常(...) ”会很容易,但不建议这样做。 另一个选择是创建一个新的异常类,如MissingDataException或InvalidDataException,但是没有针对这种情况的内置异常类?