Improve error handling in InsertObjectProcedureHandler

Wrap SQL execution in try-catch and inject SqlExceptionOptions.
Throw BadRequestException with a clear message when insert fails due to missing referenced entities, based on SqlException number. Other SQL exceptions are rethrown. This provides better feedback for foreign key/reference errors.
This commit is contained in:
Developer 02
2026-01-22 01:49:13 +01:00
parent ee793632df
commit bb5525778d

View File

@@ -1,4 +1,5 @@
using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using MediatR; using MediatR;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
using ReC.Application.Common.Exceptions; using ReC.Application.Common.Exceptions;
@@ -7,6 +8,7 @@ using ReC.Application.EndpointParams.Commands;
using ReC.Application.Endpoints.Commands; using ReC.Application.Endpoints.Commands;
using ReC.Application.Results.Commands; using ReC.Application.Results.Commands;
using ReC.Application.Profile.Commands; using ReC.Application.Profile.Commands;
using ReC.Application.Common.Options;
namespace ReC.Application.Common.Procedures.InsertProcedure; 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) public async Task<long> Handle(InsertObjectProcedure request, CancellationToken cancel)
{ {
@@ -110,18 +112,31 @@ public class InsertObjectProcedureHandler(IRepository repo) : IRequestHandler<In
} }
}; };
await repo.ExecuteQueryRawAsync( try
"EXEC [dbo].[PRREC_INSERT_OBJECT] " + {
"@pENTITY, @pADDED_WHO, @pADDED_WHEN, " + await repo.ExecuteQueryRawAsync(
"@pACTION_PROFILE_ID, @pACTION_ACTIVE, @pACTION_SEQUENCE, @pACTION_ENDPOINT_ID, @pACTION_ENDPOINT_AUTH_ID, @pACTION_ENDPOINT_PARAMS_ID, @pACTION_SQL_CONNECTION_ID, @pACTION_TYPE_ID, @pACTION_PRE_SQL, @pACTION_HEADER_SQL, @pACTION_BODY_SQL, @pACTION_POST_SQL, @pACTION_ERROR_ACTION_ID, " + "EXEC [dbo].[PRREC_INSERT_OBJECT] " +
"@pENDPOINT_ACTIVE, @pENDPOINT_DESCRIPTION, @pENDPOINT_URI, " + "@pENTITY, @pADDED_WHO, @pADDED_WHEN, " +
"@pENDPOINT_AUTH_ACTIVE, @pENDPOINT_AUTH_DESCRIPTION, @pENDPOINT_AUTH_TYPE_ID, @pENDPOINT_AUTH_API_KEY, @pENDPOINT_AUTH_API_VALUE, @pENDPOINT_AUTH_API_KEY_ADD_TO_ID, @pENDPOINT_AUTH_TOKEN, @pENDPOINT_AUTH_USERNAME, @pENDPOINT_AUTH_PASSWORD, @pENDPOINT_AUTH_DOMAIN, @pENDPOINT_AUTH_WORKSTATION, " + "@pACTION_PROFILE_ID, @pACTION_ACTIVE, @pACTION_SEQUENCE, @pACTION_ENDPOINT_ID, @pACTION_ENDPOINT_AUTH_ID, @pACTION_ENDPOINT_PARAMS_ID, @pACTION_SQL_CONNECTION_ID, @pACTION_TYPE_ID, @pACTION_PRE_SQL, @pACTION_HEADER_SQL, @pACTION_BODY_SQL, @pACTION_POST_SQL, @pACTION_ERROR_ACTION_ID, " +
"@pPROFILE_ACTIVE, @pPROFILE_TYPE_ID, @pPROFILE_MANDANTOR, @pPROFILE_NAME, @pPROFILE_DESCRIPTION, @pPROFILE_LOG_LEVEL_ID, @pPROFILE_LANGUAGE_ID, " + "@pENDPOINT_ACTIVE, @pENDPOINT_DESCRIPTION, @pENDPOINT_URI, " +
"@pRESULT_ACTION_ID, @pRESULT_STATUS_ID, @pRESULT_HEADER, @pRESULT_BODY, " + "@pENDPOINT_AUTH_ACTIVE, @pENDPOINT_AUTH_DESCRIPTION, @pENDPOINT_AUTH_TYPE_ID, @pENDPOINT_AUTH_API_KEY, @pENDPOINT_AUTH_API_VALUE, @pENDPOINT_AUTH_API_KEY_ADD_TO_ID, @pENDPOINT_AUTH_TOKEN, @pENDPOINT_AUTH_USERNAME, @pENDPOINT_AUTH_PASSWORD, @pENDPOINT_AUTH_DOMAIN, @pENDPOINT_AUTH_WORKSTATION, " +
"@pENDPOINT_PARAMS_ACTIVE, @pENDPOINT_PARAMS_DESCRIPTION, @pENDPOINT_PARAMS_GROUP_ID, @pENDPOINT_PARAMS_SEQUENCE, @pENDPOINT_PARAMS_KEY, @pENDPOINT_PARAMS_VALUE, " + "@pPROFILE_ACTIVE, @pPROFILE_TYPE_ID, @pPROFILE_MANDANTOR, @pPROFILE_NAME, @pPROFILE_DESCRIPTION, @pPROFILE_LOG_LEVEL_ID, @pPROFILE_LANGUAGE_ID, " +
"@oGUID OUTPUT", "@pRESULT_ACTION_ID, @pRESULT_STATUS_ID, @pRESULT_HEADER, @pRESULT_BODY, " +
parameters, "@pENDPOINT_PARAMS_ACTIVE, @pENDPOINT_PARAMS_DESCRIPTION, @pENDPOINT_PARAMS_GROUP_ID, @pENDPOINT_PARAMS_SEQUENCE, @pENDPOINT_PARAMS_KEY, @pENDPOINT_PARAMS_VALUE, " +
cancel); "@oGUID OUTPUT",
parameters,
cancel);
}
catch (SqlException ex)
{
if (sqlExceptionOptions.SqlExceptionNumber.Contains(ex.Number))
throw new BadRequestException(
$"Insert '{request.Entity}' failed because one or more referenced entities do not exist. " +
"Please verify the supplied identifiers and try again.\n" +
ex.Message, ex);
else
throw;
}
var guidParam = parameters.Last(); var guidParam = parameters.Last();