我想创建一个例外,我可以在其中传递结构化消息模板。那可能吗? (也可以像 Serilog 一样立即记录)
我想如何使用它的例子:
throw new NotFoundException("The book {BookId} was not found", book.Id);
最终目标是使用elasticsearch + kibana过滤错误信息。 例如“给我所有包含‘未找到书 {BookId}’且 bookid 范围在 100 到 1000 之间的日志”
我的尝试一直都是正确的。要使用消息模板记录错误,您可以传递异常、模板和参数。
例外:
public class NotFoundException : Exception
{
public object?[] Args { get; set; }
public NotFoundException(string message) : base(message)
{
Args = Array.Empty<object?>();
}
public NotFoundException(string message, params object?[] args) : base(message)
{
Args = args;
}
}
中间件/异常处理器:
try {
//Whatever
}
catch (NotFoundException e)
{
_logger.LogError(e, e.Message, e.Args);
}
仅供参考,使用它的另一个优点(除了过滤掉日志之外)是当您的异常消息中有动态数据时,您还可以更轻松地过滤掉异常。
try
{
//Do some stuff
}
catch (NotFoundException e) when (e.Message == "The book {BookId} was not found"){
//Do some more stuff
}
catch (NotFoundException e) when (Resources.BookNotFoundTemplate.Equals(e.Message)){
//Do some more stuff
}
catch (NotFoundException e) when (e.Args[0] is 1234){
//Do some more stuff
}
在测试异常消息时同样用于单元测试...
await testedMethod.Should().ThrowAsync<NotFoundException>().Where(e => e.Message == "The book {BookId} was not found");
await testedMethod.Should().ThrowAsync<NotFoundException>().Where(e => e.Args[0] is 1234);