namespace Dpz.Core.Service.Mediator.Common.Behaviors;
/// <summary>
/// Mediator 异常包装管道:统一捕获处理器异常并尝试转换为 ResponseResult。
/// </summary>
/// <typeparam name="TMessage">消息类型。</typeparam>
/// <typeparam name="TResponse">响应类型。</typeparam>
public sealed class MediatorExceptionWrappingBehavior<TMessage, TResponse>(
ILogger<MediatorExceptionWrappingBehavior<TMessage, TResponse>> logger
) : IPipelineBehavior<TMessage, TResponse>
where TMessage : IMessage
{
/// <summary>
/// 执行异常包装管道逻辑。
/// </summary>
public async ValueTask<TResponse> Handle(
TMessage message,
MessageHandlerDelegate<TMessage, TResponse> next,
CancellationToken cancellationToken
)
{
try
{
return await next(message, cancellationToken);
}
catch (Exception ex)
{
logger.LogError(
ex,
"[Mediator] Handler exception captured: {MessageName}",
typeof(TMessage).Name
);
if (TryCreateFailResponse(ex, out var wrappedResponse))
{
return wrappedResponse;
}
throw;
}
}
/// <summary>
/// 尝试根据响应类型创建统一失败结果。
/// </summary>
private static bool TryCreateFailResponse(Exception ex, out TResponse response)
{
var responseType = typeof(TResponse);
if (responseType == typeof(ResponseResult))
{
response = (TResponse)(object)ResponseResult.Fail(ex.Message, 500);
return true;
}
if (
responseType.IsGenericType
&& responseType.GetGenericTypeDefinition() == typeof(ResponseResult<>)
)
{
var method = responseType.GetMethod("WithFail", [typeof(string), typeof(int)]);
var instance = Activator.CreateInstance(responseType);
if (method == null || instance == null)
{
response = default!;
return false;
}
var value = method.Invoke(instance, [ex.Message, 500]);
if (value is TResponse casted)
{
response = casted;
return true;
}
if (instance is TResponse fallback)
{
response = fallback;
return true;
}
}
response = default!;
return false;
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个基于 MediatR 模式实现的异常包装管道行为(Pipeline Behavior)。让我详细解释一下这段代码:
代码概述
这是一个泛型类 MediatorExceptionWrappingBehavior,实现了 IPipelineBehavior 接口,用于在 Mediator 模式中统一处理异常并将其转换为标准化的响应格式。
主要功能
1. 异常捕获与处理
public async ValueTask<TResponse> Handle(...)
{
try
{
return await next(message, cancellationToken);
}
catch (Exception ex)
{
// 记录异常日志
logger.LogError(ex, "[Mediator] Handler exception captured: {MessageName}", typeof(TMessage).Name);
// 尝试创建失败响应
if (TryCreateFailResponse(ex, out var wrappedResponse))
{
return wrappedResponse;
}
// 如果无法创建失败响应,重新抛出异常
throw;
}
}
2. 智能响应转换
TryCreateFailResponse 方法通过反射机制智能判断响应类型并创建相应的失败响应:
处理 ResponseResult 类型
if (responseType == typeof(ResponseResult))
{
response = (TResponse)(object)ResponseResult.Fail(ex.Message, 500);
return true;
}
处理泛型 ResponseResult<T> 类型
if (responseType.IsGenericType &&
responseType.GetGenericTypeDefinition() == typeof(ResponseResult<>))
{
// 通过反射调用 WithFail 方法
var method = responseType.GetMethod("WithFail", [typeof(string), typeof(int)]);
var instance = Activator.CreateInstance(responseType);
var value = method.Invoke(instance, [ex.Message, 500]);
// 尝试转换并返回响应
}
设计优势
- 统一异常处理:在管道层面统一捕获和处理所有处理器异常
- 类型安全:通过泛型约束确保类型安全
- 灵活性:支持多种响应类型的自动转换
- 日志记录:自动记录异常信息便于调试
- 优雅降级:如果无法创建失败响应,会重新抛出原始异常
使用场景
这个管道行为通常在以下场景中使用:
- Web API 中统一返回格式化的错误响应
- 微服务间通信的错误处理
- 需要将内部异常转换为用户友好错误消息的场景
依赖注入
通过构造函数注入 ILogger,支持结构化日志记录,便于监控和调试。
这是一个非常实用的管道行为实现,能够显著提高应用程序的错误处理一致性和用户体验。
评论加载中...