Wrap ExecuteScalarAsync in try-catch blocks in BodyQueryBehavior and HeaderQueryBehavior. Throw DataIntegrityException with detailed context if SQL execution fails, aiding in diagnosing malformed or problematic stored SQL queries.
62 lines
2.2 KiB
C#
62 lines
2.2 KiB
C#
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using ReC.Application.Common.Dto;
|
|
using ReC.Application.Common.Exceptions;
|
|
using ReC.Application.Common.Interfaces;
|
|
using System.Text.Json;
|
|
|
|
namespace ReC.Application.Common.Behaviors.Action;
|
|
|
|
public class HeaderQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
|
where TRequest : notnull
|
|
where TResponse : IEnumerable<RecActionViewDto>
|
|
{
|
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
|
{
|
|
var actions = await next(cancel);
|
|
|
|
foreach (var action in actions)
|
|
await SetHeader(action, cancel);
|
|
|
|
return actions;
|
|
}
|
|
|
|
private async Task SetHeader(RecActionViewDto action, CancellationToken cancel)
|
|
{
|
|
if (action.HeaderQuery is not string headerQuery)
|
|
return;
|
|
|
|
await using var command = dbContext.Database.GetDbConnection().CreateCommand();
|
|
command.CommandText = headerQuery;
|
|
|
|
await dbContext.Database.OpenConnectionAsync(cancel);
|
|
try
|
|
{
|
|
object? scalar;
|
|
try
|
|
{
|
|
scalar = await command.ExecuteScalarAsync(cancel);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new DataIntegrityException(
|
|
$"Header query execution failed. The stored SQL may be malformed. ActionId: {action.Id}, ProfileId: {action.ProfileId}, Error: {ex.Message}");
|
|
}
|
|
|
|
if (scalar is not string rawHeader)
|
|
throw new DataIntegrityException(
|
|
$"Header query returned no result or a null value. ActionId: {action.Id}, ProfileId: {action.ProfileId}");
|
|
|
|
var headerDict = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(rawHeader)
|
|
?? throw new DataIntegrityException(
|
|
$"Header query returned invalid JSON. ActionId: {action.Id}, ProfileId: {action.ProfileId}");
|
|
|
|
action.Headers = headerDict.ToDictionary(header => header.Key, kvp => kvp.Value.ToString());
|
|
}
|
|
finally
|
|
{
|
|
await dbContext.Database.CloseConnectionAsync();
|
|
}
|
|
}
|
|
}
|