猿问

何时抛出异常

尽管我读了很多有关异常处理的内容,但我仍然不确定何时抛出异常,何时不抛出异常。

例如,我有一个三层架构的 API,并且在 DB 层中可能会发生事件。

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

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

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

在第一种情况下,我不会抛出异常,因为没有什么真正“出错”。我的存储库函数只是返回“null”来告诉上层没有找到任何内容。但另外两种情况已经很棘手了。

如果找不到 id,deleteById 函数返回“null”,这对我来说没有意义。如果删除不成功,我可以返回“false”;如果删除成功,我可以返回“true”。但随后我必须将其从数据库层通过领域层传输到表示层。抛出异常对我来说很容易。但在这种情况下,我也没有产生“意外行为”。就像第一种情况一样,没有什么“出错”。难道就没有什么“最佳实践”吗?

你会怎么办?


当年话下
浏览 110回答 3
3回答

鸿蒙传说

我认为在任何这些情况下都不应该抛出异常 - 原因如下:异常应该用于特殊的事情 - 主要是你无法在代码中控制的事情 - 例如网络连接错误和类似的事情。尝试从数据库接收客户,但未找到具有给定 ID 的客户。嗯,这是理所当然的 - 您在数据库中没有找到客户 - 返回 null。没有理由抛出异常,因为在这种情况下没有什么异常。尝试通过id删除客户,但在数据库中找不到该id。如果在数据库中找到该客户,则此操作将导致删除该客户。如果在数据库中没有找到它 - 最终结果仍然与找到它一样 - 那么你为什么要关心它一开始就不存在呢?同样,没有理由抛出异常。尝试通过 ID更新客户,但在数据库中找不到该 ID。这是最难解释的,但基本上有两种合法的方法来处理这种情况:一种方法是,当更新语句具有不适合表中任何行的 where 子句时,执行任何数据库执行的操作 - 这只是什么也不执行。至于让客户端知道是否有实际更新或无操作,您可以检查受影响的行数并向客户端返回 true/false 或 customer/null。另一种方法是将更新转换为“更新插入” - 因此,如果在数据库中找不到该客户,只需创建一个新客户即可。这也可以使用简单的真/假返回值向客户端指示。在这种情况下,您应该正确命名该方法 -AddOrUpdateCustomer例如。

拉风的咖菲猫

您不应使用异常作为向调用者发出预期执行流程信号的方式。当函数返回时,应该返回一个有意义的值。如果你的函数返回比较复杂,无法用简单的true/ falsereturns 来表达,你可以声明 anenum作为返回值,甚至Tuple在更复杂的场景中也可以声明 a 。尝试从数据库接收客户,但未找到具有给定 ID 的客户。尝试通过id删除客户,但在数据库中找不到该id。尝试通过 ID 更新客户,但在数据库中找不到该 ID。所有这 3 种可能的情况都应该由数据库很好地处理,当这样的路径发生时,只需向调用者返回一个包含足够信息的值,以便它可以处理结果并正确执行操作。

元芳怎么了

当出现意外错误时,您必须抛出异常。以你的例子=>getById 调用返回项 | 如果没有找到则为 null => 如果不存在则没有错误repo.Delete 函数必须有一个有效的 id => db 函数抛出异常(如果 ArgumentException 更好)...但是控制器/管理器需要 catch(ArgumentException) 然后有 2 个选项:2a. '删除不存在的项目' => 成功 -> 方法调用后,项目不存在2b. es:控制器向客户端发送错误消息“您要删除的项目不存在”repo.Update 函数必须具有有效的 id => 像上面那样没有 2a 选项如果函数需要这个参数=>抛出if 函数管理 'not found=null' case => 不抛出
随时随地看视频慕课网APP
我要回答