/**
 * Base error class for data access related errors. This class provides structured error
 * handling with type-safe error codes and optional additional data.
 *
 * Features:
 * - Type-safe error codes using string literals
 * - Optional additional error data with type safety
 * - Standardized error message format
 *
 * @template TCode - String literal type for the error code. Enforces type safety for error codes.
 * @template TData - Type for additional error data (defaults to void). Allows attaching context-specific data.
 *
 * @example
 * ```typescript
 * // Define an error with a specific code and no data
 * class MyError extends DataAccessError<'MY_ERROR'> {
 *   constructor(message: string) {
 *     super('MY_ERROR', message);
 *   }
 * }
 *
 * // Define an error with data
 * class ValidationError extends DataAccessError<'VALIDATION_ERROR', string[]> {
 *   constructor(errors: string[]) {
 *     super('VALIDATION_ERROR', 'Validation failed', errors);
 *   }
 * }
 * ```
 *
 * @see {@link PropertyIsEmptyError} for example implementation with no data
 * @see {@link CreateReturnProcessError} for example implementation with data
 */
export class DataAccessError<TCode extends string, TData = void> extends Error {
  /**
   * Creates a new DataAccessError instance.
   *
   * @param code - The error code that identifies the type of error. Must match the TCode type parameter.
   * @param message - A human-readable description of the error.
   * @param data - Additional data related to the error. Must match the TData type parameter.
   */
  constructor(
    public readonly code: TCode,
    message: string,
    public readonly data: TData,
  ) {
    super(message);
    Object.setPrototypeOf(this, new.target.prototype);
    this.name = new.target.name;
  }
}
