为了账号安全,请及时绑定邮箱和手机立即绑定

何时抛出异常

何时抛出异常

C#
当年话下 2023-09-16 17:25:27
尽管我读了很多有关异常处理的内容,但我仍然不确定何时抛出异常,何时不抛出异常。例如,我有一个三层架构的 API,并且在 DB 层中可能会发生事件。尝试从数据库接收客户,但未找到具有给定 ID 的客户。尝试通过id删除客户,但在数据库中找不到该id。尝试通过 ID更新客户,但在数据库中找不到该 ID。在第一种情况下,我不会抛出异常,因为没有什么真正“出错”。我的存储库函数只是返回“null”来告诉上层没有找到任何内容。但另外两种情况已经很棘手了。如果找不到 id,deleteById 函数返回“null”,这对我来说没有意义。如果删除不成功,我可以返回“false”;如果删除成功,我可以返回“true”。但随后我必须将其从数据库层通过领域层传输到表示层。抛出异常对我来说很容易。但在这种情况下,我也没有产生“意外行为”。就像第一种情况一样,没有什么“出错”。难道就没有什么“最佳实践”吗?你会怎么办?
查看完整描述

3 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

我认为在任何这些情况下都不应该抛出异常 - 原因如下:
异常应该用于特殊的事情 - 主要是你无法在代码中控制的事情 - 例如网络连接错误和类似的事情。

  • 尝试从数据库接收客户,但未找到具有给定 ID 的客户。

嗯,这是理所当然的 - 您在数据库中没有找到客户 - 返回 null。没有理由抛出异常,因为在这种情况下没有什么异常。

  • 尝试通过id删除客户,但在数据库中找不到该id。

如果在数据库中找到该客户,则此操作将导致删除该客户。
如果在数据库中没有找到它 - 最终结果仍然与找到它一样 - 那么你为什么要关心它一开始就不存在呢?同样,没有理由抛出异常。

  • 尝试通过 ID更新客户,但在数据库中找不到该 ID。

这是最难解释的,但基本上有两种合法的方法来处理这种情况:

一种方法是,当更新语句具有不适合表中任何行的 where 子句时,执行任何数据库执行的操作 - 这只是什么也不执行。
至于让客户端知道是否有实际更新或无操作,您可以检查受影响的行数并向客户端返回 true/false 或 customer/null。

另一种方法是将更新转换为“更新插入” - 因此,如果在数据库中找不到该客户,只需创建一个新客户即可。
这也可以使用简单的真/假返回值向客户端指示。在这种情况下,您应该正确命名该方法 -AddOrUpdateCustomer例如。


查看完整回答
反对 回复 2023-09-16
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

您不应使用异常作为向调用者发出预期执行流程信号的方式。当函数返回时,应该返回一个有意义的值。如果你的函数返回比较复杂,无法用简单的truefalsereturns 来表达,你可以声明 anenum作为返回值,甚至Tuple在更复杂的场景中也可以声明 a 。

尝试从数据库接收客户,但未找到具有给定 ID 的客户。

尝试通过id删除客户,但在数据库中找不到该id。

尝试通过 ID 更新客户,但在数据库中找不到该 ID。

所有这 3 种可能的情况都应该由数据库很好地处理,当这样的路径发生时,只需向调用者返回一个包含足够信息的值,以便它可以处理结果并正确执行操作。


查看完整回答
反对 回复 2023-09-16
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

当出现意外错误时,您必须抛出异常。以你的例子=>

  1. getById 调用返回项 | 如果没有找到则为 null => 如果不存在则没有错误

  2. repo.Delete 函数必须有一个有效的 id => db 函数抛出异常(如果 ArgumentException 更好)...但是控制器/管理器需要 catch(ArgumentException) 然后有 2 个选项:

    2a. '删除不存在的项目' => 成功 -> 方法调用后,项目不存在

    2b. es:控制器向客户端发送错误消息“您要删除的项目不存在”

  3. repo.Update 函数必须具有有效的 id => 像上面那样没有 2a 选项

如果函数需要这个参数=>抛出

if 函数管理 'not found=null' case => 不抛出


查看完整回答
反对 回复 2023-09-16
  • 3 回答
  • 0 关注
  • 109 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信