可以处理错误的组件的异常或返回状态
我目前正在设计一个处理不同类型文件的系统。我定义了以下接口
public interface IFileProcessor
{
bool ProcessFile(string fileContents)
}
,目的是创建许多具体的实现来处理不同的文件类型。控制器类将负责:
- 监视文件夹中新添加的文件
- 读取文件内容
- 获取这些 IFileProcessor 具体实现的集合
- 逐个调用每个组件上的 ProcessFile(),传递文件内容
- 如果组件无法处理该文件文件它返回 false,否则它将处理内容并返回 true
- 如果没有 IFileProcessor 实现可以处理该文件,则控制器会将其移动到“未处理”文件夹
- 如果组件成功处理该文件,则会将其移动到“已处理”文件夹
- 如果一个组件抛出异常,它被移动到“失败”文件夹
我正在创建 IFileProcessor 的实现,它将首先检查它是否可以根据类型(即 csv)处理文件,然后执行一些顶级验证(即检查文件头)。如果这些检查中的任何一个失败,都会向控制器抛出异常,因为整个文件被视为无效。
然而,一旦顶级验证成功,组件将处理文件中的每一行。从此时开始,单个行处理(即验证)失败是可以接受的,而其余的过程继续进行。
这就是问题所在,我想知道是否最好记录已发生的验证错误,然后在进程结束时抛出异常,或者更改 ProcessFile() 签名以返回枚举(已处理、未处理之一) ,已处理错误)?
从我所读到的内容来看,异常似乎是优于状态代码的首选途径,但是在流程可以继续的特殊情况下,在最后使用人为异常来声明流程未 100% 完成似乎是错误的。
我真的很想知道人们对此的想法。
I'm currently designing a system which handles the processing of different types of files. I have defined the following interface
public interface IFileProcessor
{
bool ProcessFile(string fileContents)
}
with the aim of creating a number of concrete implementations to process different file types. A controller class will be responsible for:
- Watching a folder for a newly added file
- Reading the file contents
- Obtaining a collection of these IFileProcessor concrete implementations
- One by one call the ProcessFile() on each component, passing the file contents
- If a component cannot process the file it returns false, otherwise it will process the contents and return true
- If no IFileProcessor implementation can process the file it is moved by the controller to a 'UnProcessed' folder
- If a component successfully processes the file it is moved to the 'Processed' folder
- If an exception is thrown by a component it is moved to a 'Failed' folder
I am creating an implementation of IFileProcessor which will firstly check if it can process the file based on the type (i.e. csv) and will then perform some top level validation (i.e. check file headers). If any of these checks fail an exception will the thrown to the controller, as the entire file is seen as invalid.
However once the top level validation has been successful the component will process each line in the file. From this point onwards it is acceptable for an individual line to fail processing (i.e. validation), and the rest of the process to continue.
This is where the problem lies, I am wondering if its best to log that validation errors have occurred and then throw an exception at the end of the process, or to change the ProcessFile() signature to return an enum (one of Processed, UnProcessed, ProcessedWithErrors)?
From what I have read it seems that exceptions are the preferred route over status codes, however in this particular circumstance where a process can continue it seems wrong to use an artificial exception at the end to state the process did not complete 100%.
I would be really interested in peoples thoughts on this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个建议:
不要返回 bool 或 enum,而是返回一个调用者可以检查的对象。也许称之为 FileProcessorResult。在该对象中,您可以存储各种信息,例如总体成功或失败、验证状态、处理状态等。
在严重失败的情况下,我会返回异常,以便调用者可以采取正确的操作。您可以派生一个异常类,以便 try catch 是干净的。
示例:
我可能无法给出绝对正确的答案,因此请将此作为建议。
One suggestion:
Instead of returning a bool or an enum, have it return an object which callers can inspect. Maybe call it FileProcessorResult. In the object you can store all kinds of information like overall success or failure, validation status, processing status, etc.
In cases of severe failure, I would return an exception back, so correct action could take place by the caller. You could derive an exception class so that the try catch is clean.
Example:
There is probably no absolute correct answer I can give, so please take this as a suggestion.
我不认为这是一个绝对的问题,因为我没有看到明确的做这个/做那个答案......
不过我同意你的观点,在函数末尾抛出异常确实看起来很奇怪为了发出部分处理信号,我还会使用返回代码,并在函数完全失败时抛出异常(即无法从文件读取等)。
这样做的一个很好的理由是,调用函数中可能不会处理异常,并且您可能不希望在文件被部分处理时停止执行,对吧?
无论您选择哪条路,您都需要彻底记录抛出的返回码/异常,其他人会为此感谢您。
I don't believe this to be an absolute question, as in I don't see a clear do this/do that answer...
I agree with you though, it does seem weird to throw an exception at the end of the function to signal partial processing, I would also go with the return code and throw an exception when the function failed completely (i.e. failed to read from file, etc.).
One good reason for this is that the exception might not be handled in the calling function, and you probably don't want execution to stop if the file was partially processed, right?
Whichever road you choose, you need to thoroughly document the return codes/exceptions thrown, others will thank you for it.