File: ContractNotAvailableException.cs
Web Access
Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Abstractions\Microsoft.Diagnostics.DataContractReader.Abstractions.csproj (Microsoft.Diagnostics.DataContractReader.Abstractions)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Microsoft.Diagnostics.DataContractReader;

/// <summary>
/// Exception for failures to retrieve a data contract from a target. The concrete subclasses
/// describe the specific cause; this base type is also thrown directly for an unclassified
/// validation failure. Each concrete subclass sets a distinct <see cref="CdacHResults"/> value on
/// <see cref="System.Exception.HResult"/> so both the eager validation path
/// (<see cref="Microsoft.Diagnostics.DataContractReader.Contracts.CoreCLRContracts.ValidateForDataAccess"/>)
/// and the lazy SOS data-access path surface the same self-describing failure code with no wrapping
/// or translation. The base defaults to <see cref="CdacHResults.CDAC_E_CONTRACT_UNAVAILABLE"/> so an
/// unclassified failure still carries a cDAC-specific failure code rather than <c>S_OK</c>.
/// </summary>
public class ContractNotAvailableException : Exception
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ContractNotAvailableException"/> class.
    /// </summary>
    /// <param name="contractName">The name of the requested contract.</param>
    /// <param name="contractVersion">The target-advertised version of the requested contract, or <see langword="null"/> if the target did not advertise the contract.</param>
    /// <param name="message">The exception message.</param>
    public ContractNotAvailableException(string contractName, string? contractVersion, string message)
        : base(message)
    {
        ContractName = contractName;
        ContractVersion = contractVersion;
        HResult = CdacHResults.CDAC_E_CONTRACT_UNAVAILABLE;
    }

    /// <summary>
    /// Gets the name of the requested contract.
    /// </summary>
    public string ContractName { get; }

    /// <summary>
    /// Gets the target-advertised version of the requested contract, or <see langword="null"/> if the target did not advertise the contract.
    /// </summary>
    public string? ContractVersion { get; }
}

/// <summary>
/// Exception thrown when the target's contract descriptor does not advertise the requested contract.
/// </summary>
public sealed class ContractMissingException : ContractNotAvailableException
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ContractMissingException"/> class.
    /// </summary>
    /// <param name="contractName">The name of the requested contract.</param>
    public ContractMissingException(string contractName)
        : base(contractName, null, $"Contract '{contractName}' is not advertised by the target.")
    {
        HResult = CdacHResults.CDAC_E_CONTRACT_NOT_ADVERTISED;
    }
}

/// <summary>
/// Exception thrown when the target advertises the requested contract, but this cDAC cannot provide an implementation for the advertised version.
/// </summary>
public abstract class ContractUnsupportedException : ContractNotAvailableException
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ContractUnsupportedException"/> class.
    /// </summary>
    /// <param name="contractName">The name of the requested contract.</param>
    /// <param name="contractVersion">The target-advertised version of the requested contract.</param>
    /// <param name="message">The exception message.</param>
    protected ContractUnsupportedException(string contractName, string contractVersion, string message)
        : base(contractName, contractVersion, message)
    { }
}

/// <summary>
/// Exception thrown when the target advertises a contract version that this cDAC does not recognize, typically because the target runtime is newer than this cDAC.
/// </summary>
public sealed class ContractUnrecognizedException : ContractUnsupportedException
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ContractUnrecognizedException"/> class.
    /// </summary>
    /// <param name="contractName">The name of the requested contract.</param>
    /// <param name="contractVersion">The target-advertised version of the requested contract.</param>
    public ContractUnrecognizedException(string contractName, string contractVersion)
        : base(contractName, contractVersion, $"Contract '{contractName}' version {contractVersion} is advertised by the target but is not recognized by this cDAC.")
    {
        HResult = CdacHResults.CDAC_E_CONTRACT_UNRECOGNIZED;
    }
}

/// <summary>
/// Exception thrown when the target advertises a contract version that this cDAC recognizes but intentionally does not implement, typically because the target runtime is too old.
/// </summary>
public sealed class ContractObsoleteException : ContractUnsupportedException
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ContractObsoleteException"/> class.
    /// </summary>
    /// <param name="contractName">The name of the requested contract.</param>
    /// <param name="contractVersion">The target-advertised version of the requested contract.</param>
    public ContractObsoleteException(string contractName, string contractVersion)
        : base(contractName, contractVersion, $"Contract '{contractName}' version {contractVersion} is advertised by the target and recognized by this cDAC, but is intentionally not implemented.")
    {
        HResult = CdacHResults.CDAC_E_CONTRACT_UNSUPPORTED;
    }
}