错误管理概述
让我们来学习整洁架构中的错误管理。
概述
在每个软件项目中,很大一部分代码都用于错误处理。这部分代码必须可靠无误。然而,实际情况中我们常常发现遗漏了某些会产生错误的情况,或者设置了自认为绝不会失败但实际上却出错的条件。
在整洁架构中,核心流程是用例的创建与执行。正如预期,这里也是错误的主要来源。因此,错误管理应当在用例层实现。这并不是说领域模型层不会产生错误——但由于这些模型是由用例创建的,那些未被模型自身处理的错误,自然就归为用例的错误。
请求与响应
我们可以将错误处理代码分为两个部分:
- 第一部分负责表示和管理请求,即传入用例的输入数据。
- 第二部分涉及如何通过响应(输出数据)从用例返回结果。
这两个概念不应与HTTP请求和响应混淆,尽管它们之间存在相似之处。我们现在关注的是数据如何传递给用例以及如何从中获取结果,以及在此过程中如何管理错误。这与该架构可能用于暴露HTTP API的其他用途无关。
请求与响应对象
请求和响应对象是整洁架构的重要组成部分,因为它们负责将调用参数、输入和结果从应用程序外部传输到用例层。
具体来说,请求对象由外部API调用生成,用于处理诸如值不正确、参数缺失、格式错误等问题。而响应对象不仅要包含API调用的实际结果,还应能够表示错误情况,并提供关于问题发生的详细信息。
请求和响应对象的具体实现完全由我们自行决定。整洁架构对此并无规定,如何封装和表达数据取决于我们的设计选择。
支持过滤功能
为了开始处理潜在错误并理解其管理方式,我们将扩展 room_list_use_case 以支持过滤功能。这些过滤器可用于从存储中选择 Room 对象的一个子集。
例如,过滤器可以表示为一个字典,其中包含 Room 模型的属性及希望应用的逻辑。一旦接受这种复杂结构,我们的用例就可能面临以下错误:
- 模型中不存在的属性;
- 类型错误的阈值;
- 导致存储层崩溃的过滤条件。
所有这些情况都必须由用例来考虑和处理。
基本结构
在扩展用例以支持过滤器之前,我们可以先实现结构化的请求。
处理请求
为了处理请求,我们只需要 RoomListRequest 类。该类可以在无参数的情况下初始化。让我们创建 tests/requests/test_room_list.py 文件,并为其添加测试:
1from rentomatic.requests.room_list import RoomListRequest 2 3def test_build_room_list_request_without_parameters(): 4 request = RoomListRequest() 5 assert bool(request) is True 6 7 8def test_build_room_list_request_from_empty_dict(): 9 request = RoomListRequest.from_dict({}) 10 assert bool(request) is True
虽然目前这个请求对象是空的,但一旦 list 用例开始接收参数,它就会变得非常有用。RoomListRequest 类的代码如下:
1class RoomListRequest: 2 @classmethod 3 def from_dict(cls, adict): 4 return cls() 5 6 def __bool__(self): 7 return True
编写响应
响应对象同样很简单,因为目前我们只需返回成功结果即可。与请求不同,响应并不绑定于特定用例,因此我们可以将测试文件命名为 tests/test_responses.py。响应的测试代码如下:
1from rentomatic.responses import ResponseSuccess 2 3def test_response_success_is_true(): 4 assert bool(ResponseSuccess()) is True
实际的响应对象位于 rentomatic/responses.py 文件中,代码如下:
1class ResponseSuccess: 2 def __init__(self, value=None): 3 self.value = value 4 5 def __bool__(self): 6 return True
借助这两个对象,我们为更完善的用例输入输出管理打下了基础,尤其是在处理错误情形时。
更新后的代码
在代码编辑器中,我们已使用新代码更新了相关文件。