Freigeben über


Fehlerbehandlung im Azure SDK für C++

Die Fehlerbehandlung im Azure SDK für C++ wird in erster Linie über C++-Ausnahmen implementiert. Dieser Ansatz richtet sich an standardmäßige C++-Methoden und ermöglicht eine klare Fehlerberichterstattung und -behandlung im gesamten SDK. Wenn Ihre C++-Anwendung mit Azure-Diensten interagiert, können Vorgänge aus verschiedenen Gründen fehlschlagen, z. B. Authentifizierungsprobleme, Dienstverfügbarkeit, ungültige Anforderungen oder Ressourceneinschränkungen. Das SDK erfasst diese Fehler als Ausnahmen, die detaillierte Informationen zum Fehler bereitstellen.

Ausnahmehierarchie

Kern-Ausnahmetypen

Das Azure SDK für C++ verwendet eine Hierarchie von Ausnahmeklassen, wobei die wichtigsten sind:

  1. std::runtime_error – Die C++-Basisstandard-Ausnahme, von der azurespezifische Ausnahmen erben.

  2. Azure::Core::RequestFailedException – Abgeleitet von std::runtime_error, ist dies die Basis-Ausnahme für alle Azure-Dienstanforderungsfehler. azure/core/exception.hppDiese Ausnahme wird ausgelöst, wenn eine Anforderung an einen Azure-Dienst fehlschlägt. Sie bietet:

    • HTTP-Statuscode
    • Fehlercodes vom Dienst
    • Fehlermeldungen
    • Anfordern von IDs zur Problembehandlung
    • Die unformatierte HTTP-Antwort
  3. Azure::Core::OperationCancelledException - Von std::runtime_error abgeleitet, wird diese Ausnahme ausgelöst, wenn ein Vorgang abgebrochen wird, in der Regel über ein Kontextobjekt.

  4. Azure::Core::Http::TransportException - Diese aus Azure::Core::RequestFailedException abgeleitete Ausnahme wird ausgelöst, wenn in der HTTP-Transportebene ein Fehler auftritt, z. B. bei Verbindungsfehlern.

  5. Abgeleitet von Azure::Core::Credentials::AuthenticationException wird diese Ausnahme ausgelöst, wenn die Authentifizierung mit Azure-Diensten fehlschlägt.

Dienstspezifische Ausnahmetypen

Verschiedene Azure-Dienste erweitern die Basis-Ausnahmetypen, um dienstspezifische Fehlerinformationen bereitzustellen:

  1. Azure::Storage::StorageException - Erweitert RequestFailedException durch weitere speicherspezifische Informationen. Diese Ausnahme umfasst:

    • Speicherspezifische Fehlercodes
    • Zusätzliche Informationen im Antworttext
    • Details zum fehlgeschlagenen Speichervorgang
  2. Azure::Messaging::EventHubs::EventHubsException – Eine Ausnahme, die für Event Hubs-Vorgänge spezifisch ist. Sie umfasst Folgendes:

    • Fehlerbedingung (symbolischer Wert aus AMQP (Advanced Message Queuing Protocol))
    • Fehlerbeschreibung
    • Statuscode
    • Informationen dazu, ob der Fehler vorübergehend ist

Fehlerinformationen in Ausnahmen

Die RequestFailedException Klasse enthält umfassende Informationen zu Dienstfehlern:

class RequestFailedException : public std::runtime_error {
public:
    // The entire HTTP raw response
    std::unique_ptr<Azure::Core::Http::RawResponse> RawResponse;
    
    // The HTTP response code
    Azure::Core::Http::HttpStatusCode StatusCode;
    
    // The HTTP reason phrase from the response
    std::string ReasonPhrase;
    
    // The client request header (x-ms-client-request-id) from the HTTP response
    std::string ClientRequestId;
    
    // The request ID header (x-ms-request-id) from the HTTP response
    std::string RequestId;
    
    // The error code from service returned in the HTTP response
    std::string ErrorCode;
    
    // The error message from the service returned in the HTTP response
    std::string Message;
    
    /* ... constructors and other methods ... */
};

Dienstspezifische Ausnahmen können zusätzliche Felder hinzufügen. Zum Beispiel fügt StorageException Folgendes hinzu: AdditionalInformation

struct StorageException final : public Azure::Core::RequestFailedException {
    // Some storage-specific information in response body
    std::map<std::string, std::string> AdditionalInformation;
    
    /* ... constructors and other methods ... */
};

Muster und Beispiele für die Ausnahmebehandlung

Verwenden von Fehlercodes

Dienst-Ausnahmen enthalten ErrorCode Werte, die verwendet werden können, um Entscheidungen darüber zu treffen, wie Fehler behandelt werden sollen. Hier ist ein Beispiel für Speicherdienste:

try {
    containerClient.Delete();
}
catch (Azure::Storage::StorageException& e) {
    if (e.ErrorCode == "ContainerNotFound") {
        // Ignore the error if the container does not exist
    }
    else {
        // Handle other errors here
    }
}

Behandeln grundlegender Ausnahmen

Grundlegendes Muster für die Behandlung von Ausnahmen im Azure SDK:

try {
    // Perform an Azure SDK operation
    result = client.SomeOperation();
}
catch (Azure::Core::RequestFailedException const& e) {
    std::cout << "Request Failed Exception happened:" << std::endl << e.what() << std::endl;
    if (e.RawResponse) {
        std::cout << "Error Code: " << e.ErrorCode << std::endl;
        std::cout << "Error Message: " << e.Message << std::endl;
    }
    // Handle or rethrow as appropriate
}
catch (std::exception const& e) {
    std::cout << "Other exception: " << e.what() << std::endl;
    // Handle general exceptions
}

Behandeln vorübergehender Fehler

Einige Dienste, z. B. Event Hubs, stellen Informationen darüber bereit, ob ein Fehler vorübergehend ist, was die Wiederholungslogik ermöglicht:

try {
    // EventHubs operation
}
catch (Azure::Messaging::EventHubs::EventHubsException& e) {
    if (e.IsTransient) {
        // Retry the operation after a delay
    }
    else {
        // Handle permanent failure
    }
}

Das SDK implementiert interne Wiederholungsrichtlinien für vorübergehende Fehler, aber Sie möchten bestimmte Fälle in Ihrem Anwendungscode behandeln.

Dienstspezifische Fehlerbehandlung

Für Speicherdienste (Blobs, Dateien, Warteschlangen usw.) können Sie Fehler basierend auf Fehlercodes und HTTP-Statuscodes behandeln:

try {
    shareClient.Delete();
}
catch (Azure::Storage::StorageException& e) {
    if (e.ErrorCode == "ShareNotFound") {
        // Ignore the error if the file share does not exist
    }
    else if (e.StatusCode == Azure::Core::Http::HttpStatusCode::Conflict) {
        // Handle conflict error (e.g., resource in use)
        std::cout << "Conflict error: " << e.Message << std::endl;
        
        // Check additional information
        for (auto const& info : e.AdditionalInformation) {
            std::cout << info.first << ": " << info.second << std::endl;
        }
    }
    else {
        // Handle other errors based on status code or error code
        std::cout << "Error: " << e.Message << " (Code: " << e.ErrorCode << ")" << std::endl;
    }
}

Bei Key Vault-Vorgängen müssen Sie eventuell Authentifizierungsausnahmen separat behandeln.

try {
    // Key Vault operation
}
catch (Azure::Core::Credentials::AuthenticationException const& e) {
    std::cout << "Authentication Exception happened:" << std::endl << e.what() << std::endl;
    // Handle authentication failure (e.g., invalid credentials)
}
catch (Azure::Core::RequestFailedException const& e) {
    std::cout << "Key Vault Client Exception happened:" << std::endl << e.Message << std::endl;
    // Handle Key Vault specific errors
}

Überlegungen zur Threadsicherheit

Das Azure SDK für C++ garantiert, dass Clientinstanzmethoden threadsicher und unabhängig voneinander sind. Dies bedeutet, dass Sie eine Clientinstanz ohne Synchronisierung sicher über mehrere Threads hinweg verwenden können.

Beachten Sie beim Behandeln von Ausnahmen über Threads hinweg Folgendes:

  1. Ausnahmeobjekte sollten nicht zwischen Threads gemeinsam verwendet werden, es sei denn, sie wurden ordnungsgemäß synchronisiert.
  2. Enthält RequestFailedException einen Kopierkonstruktor, der eine tiefe Kopie erstellt, die verwendet werden kann, wenn Ausnahmeinformationen zwischen Threads übergeben werden müssen.