CommandResult
When a command is executed, it returns a CommandResult<TResponse> that provides comprehensive information about the execution outcome. The result includes success/failure status, validation errors, authorization status, exceptions, and optional response data.
Structure
Section titled “Structure”The CommandResult interface provides the following properties:
interface ICommandResult<TResponse = object> { readonly correlationId: Guid; readonly isSuccess: boolean; readonly isAuthorized: boolean; readonly isValid: boolean; readonly hasExceptions: boolean; readonly validationResults: ValidationResult[]; readonly exceptionMessages: string[]; readonly exceptionStackTrace: string; readonly response?: TResponse;}Status Properties
Section titled “Status Properties”Understanding the different status properties is crucial for proper error handling:
isSuccess
Section titled “isSuccess”Indicates whether the command executed successfully overall. This is the primary indicator of whether the operation completed as intended.
true: The command executed without any issues (authorized, valid, and no exceptions)false: The command failed for one or more reasons (could be authorization, validation, or exceptions)
Use this when:
- You want to know if the overall operation succeeded
- You need a single boolean check for success/failure
- You’re implementing simple success/failure UI feedback
const result = await command.execute();if (result.isSuccess) { // Show success message} else { // Handle failure (check other properties for details)}isAuthorized
Section titled “isAuthorized”Indicates whether Arc’s command pipeline authorized this command.
true: The user has permission to execute the commandfalse: The generated command endpoint returned an authorization failure, typically HTTP 403. An upstream authentication challenge can return HTTP 401 before aCommandResultpayload is produced.
Use this when:
- You need to distinguish authorization failures from other errors
- You want to show specific “access denied” messages
- You need to redirect users to login or show permission requests
const result = await command.execute();if (!result.isAuthorized) { // Show "Access Denied" message // Redirect to login or request permissions}isValid
Section titled “isValid”Indicates whether the command payload passed validation rules.
true: All validation rules passedfalse: One or more validation rules failed (checkvalidationResultsfor details)
Use this when:
- You need to display validation errors to users
- You want to highlight invalid form fields
- You’re implementing client-side validation feedback
const result = await command.execute();if (!result.isValid) { // Display validation errors from result.validationResults result.validationResults.forEach(error => { console.log(`${error.members.join('.')}: ${error.message}`); });}hasExceptions
Section titled “hasExceptions”Indicates whether any exceptions occurred during command execution.
true: One or more exceptions were thrownfalse: No exceptions occurred
Use this when:
- You need to catch unexpected server errors
- You want to log errors for debugging
- You need to show generic error messages for system failures
const result = await command.execute();if (result.hasExceptions) { // Log exception details console.error('Exceptions:', result.exceptionMessages); console.error('Stack trace:', result.exceptionStackTrace);
// Show user-friendly error message showErrorMessage('An unexpected error occurred. Please try again.');}Understanding the Relationship
Section titled “Understanding the Relationship”The status properties work together to provide a complete picture:
// Scenario 1: Complete success// isSuccess = true, isAuthorized = true, isValid = true, hasExceptions = false
// Scenario 2: Authorization failure// isSuccess = false, isAuthorized = false, isValid = true, hasExceptions = false
// Scenario 3: Validation failure// isSuccess = false, isAuthorized = true, isValid = false, hasExceptions = false
// Scenario 4: Exception occurred// isSuccess = false, isAuthorized = true, isValid = true, hasExceptions = true
// Scenario 5: Multiple failures (validation + exception)// isSuccess = false, isAuthorized = true, isValid = false, hasExceptions = trueKey principle: If isSuccess is false, check the other properties to determine why it failed.
Accessing Data
Section titled “Accessing Data”Response Data
Section titled “Response Data”When the command returns data, access it through the response property:
interface CreateAccountResponse { accountId: string; accountNumber: string;}
const result = await createAccountCommand.execute();if (result.isSuccess && result.response) { const { accountId, accountNumber } = result.response; console.log(`Account created: ${accountNumber}`);}The response is typed according to the command’s generic parameter, providing full type safety.
Validation Results
Section titled “Validation Results”Access detailed validation errors through the validationResults array:
const result = await command.execute();if (!result.isValid) { result.validationResults.forEach(error => { console.log(`Severity: ${error.severity}`); console.log(`Message: ${error.message}`); console.log(`Members: ${error.members.join('.')}`); console.log(`State: ${JSON.stringify(error.state)}`); });}Each ValidationResult contains:
severity: The severity level of the validation errormessage: Human-readable error messagemembers: Array of property names that failed validationstate: Additional context about the validation failure
Exception Details
Section titled “Exception Details”Access exception information when hasExceptions is true:
const result = await command.execute();if (result.hasExceptions) { // Array of exception messages result.exceptionMessages.forEach(msg => { console.error('Exception:', msg); });
// Full stack trace for debugging console.error('Stack trace:', result.exceptionStackTrace);}Chaining Callbacks
Section titled “Chaining Callbacks”CommandResult supports a fluent API for handling different outcomes:
const result = await command.execute();
result .onSuccess((response) => { console.log('Success!', response); }) .onFailed((commandResult) => { console.log('Failed:', commandResult); }) .onUnauthorized(() => { console.log('Not authorized'); }) .onValidationFailure((validationResults) => { console.log('Validation errors:', validationResults); }) .onException((messages, stackTrace) => { console.error('Exception:', messages, stackTrace); });Each callback method returns the CommandResult instance, allowing you to chain multiple handlers.
Best Practices
Section titled “Best Practices”1. Check isSuccess First
Section titled “1. Check isSuccess First”Always start by checking isSuccess for the overall outcome:
const result = await command.execute();if (result.isSuccess) { // Handle success} else { // Check specific failure reasons if (!result.isAuthorized) { /* ... */ } if (!result.isValid) { /* ... */ } if (result.hasExceptions) { /* ... */ }}2. Provide Specific Error Messages
Section titled “2. Provide Specific Error Messages”Use the specific status properties to give users meaningful feedback:
const result = await command.execute();if (!result.isSuccess) { if (!result.isAuthorized) { showMessage('You do not have permission to perform this action.'); } else if (!result.isValid) { showValidationErrors(result.validationResults); } else if (result.hasExceptions) { showMessage('An unexpected error occurred. Please contact support.'); }}3. Log Exceptions for Debugging
Section titled “3. Log Exceptions for Debugging”Always log exception details when hasExceptions is true:
if (result.hasExceptions) { logger.error('Command execution failed', { messages: result.exceptionMessages, stackTrace: result.exceptionStackTrace, correlationId: result.correlationId });}4. Use Correlation ID for Tracking
Section titled “4. Use Correlation ID for Tracking”The correlationId helps track command executions across the system:
console.log(`Command executed with correlation ID: ${result.correlationId}`);This is especially useful for debugging and support scenarios.
Related Topics
Section titled “Related Topics”- Commands - Core command concepts and usage
- React Commands - Using commands in React components
- Validation - Understanding validation rules