Compare commits
10 Commits
86f4e3141e
...
88cb1dc16a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88cb1dc16a | ||
|
|
8d6a09213e | ||
|
|
54f412ced2 | ||
|
|
51b9c62188 | ||
|
|
bb5525778d | ||
|
|
ee793632df | ||
|
|
22bb585f60 | ||
|
|
ed7237c8dd | ||
|
|
f71bcf37e9 | ||
|
|
c7e366af60 |
@@ -12,7 +12,7 @@ namespace ReC.API.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ResultController(IMediator mediator, IConfiguration config) : ControllerBase
|
||||
public class ResultController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets output results based on the provided query parameters.
|
||||
|
||||
@@ -63,6 +63,13 @@ public class ExceptionHandlingMiddleware
|
||||
switch (exception)
|
||||
{
|
||||
case BadRequestException badRequestEx:
|
||||
if (badRequestEx.InnerException is not null)
|
||||
{
|
||||
logger.LogError(
|
||||
badRequestEx.InnerException,
|
||||
"BadRequestException inner exception captured.");
|
||||
}
|
||||
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
details = new()
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ try
|
||||
{
|
||||
options.LuckyPennySoftwareLicenseKey = builder.Configuration["LuckyPennySoftwareLicenseKey"];
|
||||
options.ConfigureRecActions(config.GetSection("RecAction"));
|
||||
options.ConfigureSqlException(config.GetSection("SqlException"));
|
||||
});
|
||||
|
||||
builder.Services.AddRecInfrastructure(options =>
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"RecAction": {
|
||||
"MaxConcurrentInvocations": 5
|
||||
},
|
||||
"SqlException": {
|
||||
"ErrorMessages": {
|
||||
// https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlexception.number
|
||||
"SqlExceptionNumber": [ 515 , 547, 2601, 2627]
|
||||
}
|
||||
},
|
||||
"AddedWho": "ReC.API",
|
||||
"FakeProfileId": 2
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ReC.Application.Common.Options;
|
||||
|
||||
public class SqlExceptionOptions
|
||||
{
|
||||
public HashSet<int> SqlExceptionNumber { get; set; } = [];
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
using ReC.Application.Common.Options;
|
||||
|
||||
namespace ReC.Application.Common.Procedures.DeleteProcedure;
|
||||
|
||||
@@ -47,7 +49,7 @@ public static class DeleteObjectProcedureExtensions
|
||||
}
|
||||
}
|
||||
|
||||
public class DeleteObjectProcedureHandler(IRepository repo) : IRequestHandler<DeleteObjectProcedure, int>
|
||||
public class DeleteObjectProcedureHandler(IRepository repo, SqlExceptionOptions sqlExceptionOptions) : IRequestHandler<DeleteObjectProcedure, int>
|
||||
{
|
||||
public async Task<int> Handle(DeleteObjectProcedure request, CancellationToken cancel)
|
||||
{
|
||||
@@ -59,6 +61,8 @@ public class DeleteObjectProcedureHandler(IRepository repo) : IRequestHandler<De
|
||||
new SqlParameter("@pFORCE", (object?)request.Force ?? DBNull.Value)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var result = await repo.ExecuteQueryRawAsync(
|
||||
"DECLARE @RC SMALLINT = 0; " +
|
||||
"EXEC @RC = [dbo].[PRREC_DELETE_OBJECT] " +
|
||||
@@ -75,4 +79,12 @@ public class DeleteObjectProcedureHandler(IRepository repo) : IRequestHandler<De
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
if (sqlExceptionOptions.SqlExceptionNumber.Contains(ex.Number))
|
||||
throw new BadRequestException(ex.Message, ex);
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
@@ -7,6 +8,7 @@ using ReC.Application.EndpointParams.Commands;
|
||||
using ReC.Application.Endpoints.Commands;
|
||||
using ReC.Application.Results.Commands;
|
||||
using ReC.Application.Profile.Commands;
|
||||
using ReC.Application.Common.Options;
|
||||
|
||||
namespace ReC.Application.Common.Procedures.InsertProcedure;
|
||||
|
||||
@@ -41,7 +43,7 @@ public static class InsertObjectProcedureExtensions
|
||||
}
|
||||
}
|
||||
|
||||
public class InsertObjectProcedureHandler(IRepository repo) : IRequestHandler<InsertObjectProcedure, long>
|
||||
public class InsertObjectProcedureHandler(IRepository repo, SqlExceptionOptions sqlExceptionOptions) : IRequestHandler<InsertObjectProcedure, long>
|
||||
{
|
||||
public async Task<long> Handle(InsertObjectProcedure request, CancellationToken cancel)
|
||||
{
|
||||
@@ -110,6 +112,8 @@ public class InsertObjectProcedureHandler(IRepository repo) : IRequestHandler<In
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await repo.ExecuteQueryRawAsync(
|
||||
"EXEC [dbo].[PRREC_INSERT_OBJECT] " +
|
||||
"@pENTITY, @pADDED_WHO, @pADDED_WHEN, " +
|
||||
@@ -122,6 +126,14 @@ public class InsertObjectProcedureHandler(IRepository repo) : IRequestHandler<In
|
||||
"@oGUID OUTPUT",
|
||||
parameters,
|
||||
cancel);
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
if (sqlExceptionOptions.SqlExceptionNumber.Contains(ex.Number))
|
||||
throw new BadRequestException(ex.Message, ex);
|
||||
else
|
||||
throw;
|
||||
}
|
||||
|
||||
var guidParam = parameters.Last();
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
using DigitalData.Core.Abstraction.Application.Repository;
|
||||
using DigitalData.Core.Exceptions;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ReC.Application.Common.Exceptions;
|
||||
using ReC.Application.Common.Options;
|
||||
using ReC.Application.EndpointAuth.Commands;
|
||||
using ReC.Application.EndpointParams.Commands;
|
||||
using ReC.Application.Endpoints.Commands;
|
||||
using ReC.Application.Results.Commands;
|
||||
using ReC.Application.Profile.Commands;
|
||||
using ReC.Application.RecActions.Commands;
|
||||
using ReC.Application.Results.Commands;
|
||||
|
||||
namespace ReC.Application.Common.Procedures.UpdateProcedure;
|
||||
|
||||
@@ -47,7 +49,7 @@ public static class UpdateObjectProcedureExtensions
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateObjectProcedureHandler(IRepository repo) : IRequestHandler<UpdateObjectProcedure, int>
|
||||
public class UpdateObjectProcedureHandler(IRepository repo, SqlExceptionOptions sqlExceptionOptions) : IRequestHandler<UpdateObjectProcedure, int>
|
||||
{
|
||||
public async Task<int> Handle(UpdateObjectProcedure request, CancellationToken cancel)
|
||||
{
|
||||
@@ -113,6 +115,8 @@ public class UpdateObjectProcedureHandler(IRepository repo) : IRequestHandler<Up
|
||||
new SqlParameter("@pRESULT_BODY", (object?)request.Result.Body ?? DBNull.Value)
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var result = await repo.ExecuteQueryRawAsync(
|
||||
"DECLARE @RC SMALLINT = 0; " +
|
||||
"EXEC @RC = [dbo].[PRREC_UPDATE_OBJECT] " +
|
||||
@@ -135,4 +139,12 @@ public class UpdateObjectProcedureHandler(IRepository repo) : IRequestHandler<Up
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
if (sqlExceptionOptions.SqlExceptionNumber.Contains(ex.Number))
|
||||
throw new BadRequestException(ex.Message, ex);
|
||||
else
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using ReC.Application.Common.Behaviors;
|
||||
using ReC.Application.Common.Constants;
|
||||
using ReC.Application.Common.Options;
|
||||
using ReC.Application.Common.Procedures;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ReC.Application;
|
||||
@@ -116,5 +118,23 @@ public static class DependencyInjection
|
||||
return this;
|
||||
}
|
||||
#endregion ConfigureRecActions
|
||||
|
||||
#region ConfigureSqlException
|
||||
public ConfigurationOptions ConfigureSqlException(Action<SqlExceptionOptions> configure)
|
||||
{
|
||||
_configActions.Enqueue(services => services.Configure(configure));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationOptions ConfigureSqlException(IConfiguration configuration)
|
||||
{
|
||||
_configActions.Enqueue(services =>
|
||||
{
|
||||
services.Configure<SqlExceptionOptions>(configuration);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
#endregion ConfigureSqlException
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<PackageReference Include="AutoMapper" Version="15.1.0" />
|
||||
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.6.0" />
|
||||
<PackageReference Include="DigitalData.Core.Application" Version="3.4.0" />
|
||||
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.0" />
|
||||
<PackageReference Include="DigitalData.Core.Exceptions" Version="1.1.1" />
|
||||
<PackageReference Include="FluentValidation" Version="12.1.0" />
|
||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.0" />
|
||||
<PackageReference Include="MediatR" Version="13.1.0" />
|
||||
|
||||
@@ -40,6 +40,7 @@ public abstract class RecApplicationTestBase : IDisposable
|
||||
{
|
||||
options.LuckyPennySoftwareLicenseKey = configuration["LuckyPennySoftwareLicenseKey"];
|
||||
options.ConfigureRecActions(configuration.GetSection("RecAction"));
|
||||
options.ConfigureSqlException(configuration.GetSection("SqlException"));
|
||||
});
|
||||
|
||||
services.AddRecInfrastructure(opt =>
|
||||
|
||||
Reference in New Issue
Block a user