Refactor exceptions to include profileId context
Refactored `JobException` and derived classes (`InactiveProfileException`, `JobHttpException`, `JobSqlException`) to include `profileId` as a required parameter in their constructors. This ensures consistent context for exceptions related to job execution. Updated behaviors (`CheckQueryExecutionBehavior`, `MainQueryExecutionBehavior`, `ReCRequestExecutionBehavior`) to use the new constructors, passing `profileId` where applicable. Improved exception messages for better debugging context. Simplified property initialization and enhanced XML documentation for clarity.
This commit is contained in:
@@ -6,42 +6,31 @@ namespace ECMJobRunner.Application.Common.Exceptions
|
|||||||
/// Exception thrown when attempting to execute a job for an inactive profile
|
/// Exception thrown when attempting to execute a job for an inactive profile
|
||||||
/// Extends JobException with profile-specific context
|
/// Extends JobException with profile-specific context
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InactiveProfileException : JobException
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of InactiveProfileException
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="profileId">ID of the inactive profile</param>
|
||||||
|
/// <param name="profileName">Name of the inactive profile (nullable)</param>
|
||||||
|
/// <param name="batchId">Unique batch identifier for tracking</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this exception when:
|
||||||
|
/// - Attempting to trigger DEX job batch for an inactive profile
|
||||||
|
/// - Attempting to execute individual jobs from an inactive profile
|
||||||
|
/// - Profile is deactivated during execution
|
||||||
|
/// </remarks>
|
||||||
|
public class InactiveProfileException(long profileId, string? profileName, string batchId) : JobException(
|
||||||
|
profileId,
|
||||||
|
jobName: "Profile Execution",
|
||||||
|
processName: "Profile Active Status Validation",
|
||||||
|
batchId: batchId,
|
||||||
|
reason: "The profile is marked as inactive and cannot be executed",
|
||||||
|
innerException: null,
|
||||||
|
("Profile ID", profileId.ToString(), false),
|
||||||
|
("Profile Name", profileName, true))
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of InactiveProfileException
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="profileId">ID of the inactive profile</param>
|
|
||||||
/// <param name="profileName">Name of the inactive profile (nullable)</param>
|
|
||||||
/// <param name="batchId">Unique batch identifier for tracking</param>
|
|
||||||
/// <remarks>
|
|
||||||
/// Use this exception when:
|
|
||||||
/// - Attempting to trigger DEX job batch for an inactive profile
|
|
||||||
/// - Attempting to execute individual jobs from an inactive profile
|
|
||||||
/// - Profile is deactivated during execution
|
|
||||||
/// </remarks>
|
|
||||||
public InactiveProfileException(long profileId, string? profileName, string batchId)
|
|
||||||
: base(
|
|
||||||
jobName: "Profile Execution",
|
|
||||||
processName: "Profile Active Status Validation",
|
|
||||||
batchId: batchId,
|
|
||||||
reason: "The profile is marked as inactive and cannot be executed",
|
|
||||||
innerException: null,
|
|
||||||
("Profile ID", profileId.ToString(), false),
|
|
||||||
("Profile Name", profileName, true))
|
|
||||||
{
|
|
||||||
ProfileId = profileId;
|
|
||||||
ProfileName = profileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ID of the inactive profile
|
|
||||||
/// </summary>
|
|
||||||
public long ProfileId { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the inactive profile (nullable)
|
/// Gets the name of the inactive profile (nullable)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ProfileName { get; }
|
public string? ProfileName { get; } = profileName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,53 +7,54 @@ namespace ECMJobRunner.Application.Common.Exceptions
|
|||||||
/// Base exception class for job execution failures
|
/// Base exception class for job execution failures
|
||||||
/// Provides a flexible structure for capturing job context and detailed error information
|
/// Provides a flexible structure for capturing job context and detailed error information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JobException : Exception
|
/// <remarks>
|
||||||
{
|
/// Initializes a new instance of JobException with detailed context information
|
||||||
/// <summary>
|
/// </remarks>
|
||||||
/// Initializes a new instance of JobException with detailed context information
|
/// <param name="profileId">Identifier of the profile associated with the job</param>
|
||||||
/// </summary>
|
/// <param name="jobName">Name of the job that failed (e.g., "SQL Main Query", "ReC Request")</param>
|
||||||
/// <param name="jobName">Name of the job that failed (e.g., "SQL Main Query", "ReC Request")</param>
|
/// <param name="processName">Name of the process/stage being executed (e.g., "MainQueryExecution", "CheckQueryValidation")</param>
|
||||||
/// <param name="processName">Name of the process/stage being executed (e.g., "MainQueryExecution", "CheckQueryValidation")</param>
|
/// <param name="batchId">Unique batch identifier for tracking the execution</param>
|
||||||
/// <param name="batchId">Unique batch identifier for tracking the execution</param>
|
/// <param name="reason">Human-readable reason for the failure (nullable)</param>
|
||||||
/// <param name="reason">Human-readable reason for the failure (nullable)</param>
|
/// <param name="innerException">The underlying exception that caused the failure (nullable)</param>
|
||||||
/// <param name="innerException">The underlying exception that caused the failure (nullable)</param>
|
/// <param name="details">Additional contextual details as name-value pairs with optional null-handling</param>
|
||||||
/// <param name="details">Additional contextual details as name-value pairs with optional null-handling</param>
|
/// <remarks>
|
||||||
/// <remarks>
|
/// The details parameter accepts tuples with:
|
||||||
/// The details parameter accepts tuples with:
|
/// - Name: Display name of the detail
|
||||||
/// - Name: Display name of the detail
|
/// - Value: String value of the detail (nullable)
|
||||||
/// - Value: String value of the detail (nullable)
|
/// - IgnoreIfNull: If true, the detail is omitted from the message when value is null
|
||||||
/// - IgnoreIfNull: If true, the detail is omitted from the message when value is null
|
/// </remarks>
|
||||||
/// </remarks>
|
public class JobException(long profileId, string jobName, string processName, string batchId, string? reason, Exception? innerException, params (string Name, string? Value, bool IgnoreIfNull)[] details)
|
||||||
public JobException(string jobName, string processName, string batchId, string? reason, Exception? innerException, params (string Name, string? Value, bool IgnoreIfNull)[] details)
|
: Exception(
|
||||||
: base(
|
CreateMessage(jobName,
|
||||||
CreateMessage(jobName,
|
|
||||||
[
|
[
|
||||||
|
("Profile Id", profileId.ToString(), false),
|
||||||
|
("Job Name", jobName, false),
|
||||||
("Process Name", processName, false),
|
("Process Name", processName, false),
|
||||||
("Batch Id", batchId, false),
|
("Batch Id", batchId, false),
|
||||||
("Reason", reason, true),
|
("Reason", reason, true),
|
||||||
..details
|
..details
|
||||||
]),
|
]),
|
||||||
innerException)
|
innerException)
|
||||||
{
|
{
|
||||||
JobName = jobName;
|
/// <summary>
|
||||||
ProcessName = processName;
|
/// Gets the profile identifier associated with the job execution
|
||||||
BatchId = batchId;
|
/// </summary>
|
||||||
}
|
public long ProfileId { get; } = profileId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the job that failed
|
/// Gets the name of the job that failed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string JobName { get; }
|
public string JobName { get; } = jobName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the process/stage that was being executed when the failure occurred
|
/// Gets the name of the process/stage that was being executed when the failure occurred
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProcessName { get; }
|
public string ProcessName { get; } = processName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the unique batch identifier for tracking the execution
|
/// Gets the unique batch identifier for tracking the execution
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BatchId { get; }
|
public string BatchId { get; } = batchId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a formatted error message with job context and details
|
/// Generates a formatted error message with job context and details
|
||||||
|
|||||||
@@ -6,41 +6,36 @@ namespace ECMJobRunner.Application.Common.Exceptions
|
|||||||
/// Exception for HTTP client-related job failures (e.g., ReC API calls, REST requests)
|
/// Exception for HTTP client-related job failures (e.g., ReC API calls, REST requests)
|
||||||
/// Extends JobException with client library and method context
|
/// Extends JobException with client library and method context
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JobHttpException : JobException
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of JobHttpException with HTTP client context
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="profileId">Identifier of the profile associated with the job</param>
|
||||||
|
/// <param name="jobName">Name of the job that failed (e.g., "ReC Request", "API Call")</param>
|
||||||
|
/// <param name="processName">Name of the process/stage being executed</param>
|
||||||
|
/// <param name="batchId">Unique batch identifier for tracking</param>
|
||||||
|
/// <param name="reason">Human-readable reason for the failure (nullable)</param>
|
||||||
|
/// <param name="clientLibrary">Name of the HTTP client library used (e.g., "ReC.Client", "HttpClient") (nullable)</param>
|
||||||
|
/// <param name="clientMethod">Name of the client method that failed (e.g., "ExecuteAsync", "PostAsync") (nullable)</param>
|
||||||
|
/// <param name="innerException">The underlying exception that caused the failure (nullable)</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this exception for HTTP-related failures such as:
|
||||||
|
/// - ReC API request failures
|
||||||
|
/// - REST API communication errors
|
||||||
|
/// - HTTP client timeout/network issues
|
||||||
|
/// - Authentication/authorization failures
|
||||||
|
/// </remarks>
|
||||||
|
public class JobHttpException(long profileId, string jobName, string processName, string batchId, string? reason, string? clientLibrary, string? clientMethod, Exception? innerException)
|
||||||
|
: JobException(profileId, jobName, processName, batchId, reason, innerException, ("Client Library", clientLibrary, true), ("Client Method", clientMethod, true))
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of JobHttpException with HTTP client context
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="jobName">Name of the job that failed (e.g., "ReC Request", "API Call")</param>
|
|
||||||
/// <param name="processName">Name of the process/stage being executed</param>
|
|
||||||
/// <param name="batchId">Unique batch identifier for tracking</param>
|
|
||||||
/// <param name="reason">Human-readable reason for the failure (nullable)</param>
|
|
||||||
/// <param name="clientLibrary">Name of the HTTP client library used (e.g., "ReC.Client", "HttpClient") (nullable)</param>
|
|
||||||
/// <param name="clientMethod">Name of the client method that failed (e.g., "ExecuteAsync", "PostAsync") (nullable)</param>
|
|
||||||
/// <param name="innerException">The underlying exception that caused the failure (nullable)</param>
|
|
||||||
/// <remarks>
|
|
||||||
/// Use this exception for HTTP-related failures such as:
|
|
||||||
/// - ReC API request failures
|
|
||||||
/// - REST API communication errors
|
|
||||||
/// - HTTP client timeout/network issues
|
|
||||||
/// - Authentication/authorization failures
|
|
||||||
/// </remarks>
|
|
||||||
public JobHttpException(string jobName, string processName, string batchId, string? reason, string? clientLibrary, string? clientMethod, Exception? innerException) : base(jobName, processName, batchId, reason, innerException,
|
|
||||||
("Client Library", clientLibrary, true),
|
|
||||||
("Client Method", clientMethod, true))
|
|
||||||
{
|
|
||||||
ClientLibrary = clientLibrary;
|
|
||||||
ClientMethod = clientMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the HTTP client library that was used (e.g., "ReC.Client", "HttpClient")
|
/// Gets the name of the HTTP client library that was used (e.g., "ReC.Client", "HttpClient")
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ClientLibrary { get; }
|
public string? ClientLibrary { get; } = clientLibrary;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the client method that failed (e.g., "ExecuteAsync", "PostAsync")
|
/// Gets the name of the client method that failed (e.g., "ExecuteAsync", "PostAsync")
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ClientMethod { get; }
|
public string? ClientMethod { get; } = clientMethod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,33 +6,30 @@ namespace ECMJobRunner.Application.Common.Exceptions
|
|||||||
/// Exception for SQL query execution failures
|
/// Exception for SQL query execution failures
|
||||||
/// Extends JobException with SQL query context for debugging
|
/// Extends JobException with SQL query context for debugging
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JobSqlException : JobException
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of JobSqlException with SQL query context
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="profileId">Identifier of the profile associated with the job</param>
|
||||||
|
/// <param name="jobName">Name of the job that failed (e.g., "Main Query Execution", "Check Query")</param>
|
||||||
|
/// <param name="processName">Name of the process/stage being executed</param>
|
||||||
|
/// <param name="batchId">Unique batch identifier for tracking</param>
|
||||||
|
/// <param name="reason">Human-readable reason for the failure (nullable)</param>
|
||||||
|
/// <param name="query">The SQL query that failed (nullable, for debugging purposes)</param>
|
||||||
|
/// <param name="innerException">The underlying SQL exception (nullable)</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this exception for SQL-related failures such as:
|
||||||
|
/// - Main query execution errors
|
||||||
|
/// - Check query validation failures
|
||||||
|
/// - Database connection issues
|
||||||
|
/// - SQL syntax errors
|
||||||
|
/// - Query timeout exceptions
|
||||||
|
///
|
||||||
|
/// The Query property can be logged for debugging but should be handled carefully
|
||||||
|
/// to avoid exposing sensitive data in production logs.
|
||||||
|
/// </remarks>
|
||||||
|
public class JobSqlException(long profileId, string jobName, string processName, string batchId, string? reason, string? query, Exception? innerException)
|
||||||
|
: JobException(profileId, jobName, processName, batchId, reason, innerException, ("Query", query, true))
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of JobSqlException with SQL query context
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="jobName">Name of the job that failed (e.g., "Main Query Execution", "Check Query")</param>
|
|
||||||
/// <param name="processName">Name of the process/stage being executed</param>
|
|
||||||
/// <param name="batchId">Unique batch identifier for tracking</param>
|
|
||||||
/// <param name="reason">Human-readable reason for the failure (nullable)</param>
|
|
||||||
/// <param name="query">The SQL query that failed (nullable, for debugging purposes)</param>
|
|
||||||
/// <param name="innerException">The underlying SQL exception (nullable)</param>
|
|
||||||
/// <remarks>
|
|
||||||
/// Use this exception for SQL-related failures such as:
|
|
||||||
/// - Main query execution errors
|
|
||||||
/// - Check query validation failures
|
|
||||||
/// - Database connection issues
|
|
||||||
/// - SQL syntax errors
|
|
||||||
/// - Query timeout exceptions
|
|
||||||
///
|
|
||||||
/// The Query property can be logged for debugging but should be handled carefully
|
|
||||||
/// to avoid exposing sensitive data in production logs.
|
|
||||||
/// </remarks>
|
|
||||||
public JobSqlException(string jobName, string processName, string batchId, string? reason, string? query, Exception? innerException) : base(jobName, processName, batchId, reason, innerException,
|
|
||||||
("Query", query, true))
|
|
||||||
{
|
|
||||||
Query = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the SQL query that failed (nullable)
|
/// Gets the SQL query that failed (nullable)
|
||||||
@@ -41,6 +38,6 @@ namespace ECMJobRunner.Application.Common.Exceptions
|
|||||||
/// This property is marked as virtual to allow derived classes to customize query handling
|
/// This property is marked as virtual to allow derived classes to customize query handling
|
||||||
/// (e.g., sanitizing sensitive data, truncating long queries)
|
/// (e.g., sanitizing sensitive data, truncating long queries)
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual string? Query { get; }
|
public virtual string? Query { get; } = query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
{
|
{
|
||||||
if (result is null)
|
if (result is null)
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Check Query",
|
processName: "Check Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
@@ -79,6 +80,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
innerException: null);
|
innerException: null);
|
||||||
else if (result.ReturnValue <= 0)
|
else if (result.ReturnValue <= 0)
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Check Query",
|
processName: "Check Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
@@ -91,6 +93,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
{
|
{
|
||||||
if (_options.Error.CheckQuery.OnExecution == ErrorAction.Stop)
|
if (_options.Error.CheckQuery.OnExecution == ErrorAction.Stop)
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Check Query",
|
processName: "Check Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
@@ -103,6 +106,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
else if (_options.Error.CheckQuery.IfNullOrWhiteSpace == ErrorAction.Stop)
|
else if (_options.Error.CheckQuery.IfNullOrWhiteSpace == ErrorAction.Stop)
|
||||||
{
|
{
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName:"Triggering DEX",
|
jobName:"Triggering DEX",
|
||||||
processName:"Check Query",
|
processName:"Check Query",
|
||||||
batchId:command.BatchId,
|
batchId:command.BatchId,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
{
|
{
|
||||||
if (result is null)
|
if (result is null)
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Main Query",
|
processName: "Main Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
@@ -79,6 +80,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
innerException: null);
|
innerException: null);
|
||||||
else if (result.ReturnValue is not null)
|
else if (result.ReturnValue is not null)
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Main Query",
|
processName: "Main Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
@@ -90,6 +92,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
{
|
{
|
||||||
if (_options.Error.MainQuery.OnExecution == ErrorAction.Stop)
|
if (_options.Error.MainQuery.OnExecution == ErrorAction.Stop)
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Main Query",
|
processName: "Main Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
@@ -101,6 +104,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
else if (_options.Error.MainQuery.IfNullOrWhiteSpace == ErrorAction.Stop)
|
else if (_options.Error.MainQuery.IfNullOrWhiteSpace == ErrorAction.Stop)
|
||||||
{
|
{
|
||||||
throw new JobSqlException(
|
throw new JobSqlException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "Main Query",
|
processName: "Main Query",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ namespace ECMJobRunner.Application.Profiles.Commands.Behaviors
|
|||||||
if (_options.Error.ReCRequest.OnSending == ErrorAction.Stop)
|
if (_options.Error.ReCRequest.OnSending == ErrorAction.Stop)
|
||||||
{
|
{
|
||||||
throw new JobHttpException(
|
throw new JobHttpException(
|
||||||
|
profileId: command.Job.ProfileId,
|
||||||
jobName: "Triggering DEX",
|
jobName: "Triggering DEX",
|
||||||
processName: "ReC Http Request",
|
processName: "ReC Http Request",
|
||||||
batchId: command.BatchId,
|
batchId: command.BatchId,
|
||||||
|
|||||||
Reference in New Issue
Block a user