Foutafhandeling in de Azure SDK voor C++

Foutafhandeling in de Azure SDK voor C++ wordt voornamelijk geïmplementeerd via C++-uitzonderingen. Deze benadering is afgestemd op de standaardprocedures voor C++ en biedt duidelijke foutrapportage en -verwerking in de SDK. Wanneer uw C++-toepassing communiceert met Azure-services, kunnen bewerkingen mislukken om verschillende redenen, zoals verificatieproblemen, servicebeschikbaarheid, ongeldige aanvragen of resourcebeperkingen. De SDK legt deze fouten vast als uitzonderingen die gedetailleerde informatie over de fout bieden.

Uitzonderingshiërarchie

Kern-uitzonderingstypen

De Azure SDK voor C++ maakt gebruik van een hiërarchie van uitzonderingsklassen, waarbij de belangrijkste zijn:

  1. std::runtime_error - De standaarduitzondering voor basis C++ waarvan Azure-specifieke uitzonderingen overnemen.

  2. Azure::Core::RequestFailedException - Afgeleid van std::runtime_error, dit is de basisuitzondering voor alle fouten in de Azure-serviceaanvraag. azure/core/exception.hppDeze uitzondering wordt gedefinieerd wanneer een aanvraag voor een Azure-service mislukt. Het biedt:

    • HTTP-statuscode
    • Foutcodes van de service
    • Foutberichten
    • Id's aanvragen voor probleemoplossing
    • Het onbewerkte HTTP-antwoord
  3. Azure::Core::OperationCancelledException - Afgeleid van std::runtime_error, deze uitzondering wordt gegenereerd wanneer een bewerking wordt geannuleerd, meestal via een contextobject.

  4. Azure::Core::Http::TransportException - Afgeleid van Azure::Core::RequestFailedException, wordt deze uitzondering gegenereerd wanneer er een fout optreedt in de HTTP-transportlaag, zoals verbindingsfouten.

  5. Azure::Core::Credentials::AuthenticationException - Afgeleid van std::exception, wordt deze uitzondering gegenereerd wanneer verificatie met Azure-services mislukt.

Servicespecifieke uitzonderingstypen

Verschillende Azure-services breiden de basisuitzonderingstypen uit om servicespecifieke foutinformatie te bieden:

  1. Azure::Storage::StorageException - Breidt uit RequestFailedException met andere opslagspecifieke informatie. Deze uitzondering omvat:

    • Opslagspecifieke foutcodes
    • Aanvullende informatie in antwoordtekst
    • Details over de mislukte opslagbewerking
  2. Azure::Messaging::EventHubs::EventHubsException - Een uitzondering die specifiek is voor Event Hubs-bewerkingen. Deze bevat:

    • Foutvoorwaarde (een symbolische waarde van Advanced Message Queuing Protocol (AMQP))
    • Foutbeschrijving
    • Statuscode
    • Informatie over of de fout tijdelijk is

Foutinformatie in uitzonderingen

De RequestFailedException klasse bevat uitgebreide informatie over servicefouten:

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 ... */
};

Servicespecifieke uitzonderingen kunnen extra velden toevoegen. Voegt bijvoorbeeld StorageException het volgende toe 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 ... */
};

Patronen en voorbeelden voor het verwerken van uitzonderingen

Foutcodes gebruiken

Serviceuitzonderingen bevatten ErrorCode waarden die kunnen worden gebruikt om beslissingen te nemen over het afhandelen van fouten. Hier volgt een voorbeeld met Opslagservices:

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
    }
}

Eenvoudige uitzonderingen verwerken

Basispatroon voor het verwerken van uitzonderingen in de 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
}

Tijdelijke fouten afhandelen

Sommige services, zoals Event Hubs, bieden informatie over of een fout tijdelijk is, waardoor logica voor opnieuw proberen mogelijk is:

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

De SDK implementeert intern beleid voor nieuwe pogingen voor tijdelijke fouten, maar mogelijk wilt u nog steeds specifieke gevallen in uw toepassingscode afhandelen.

Servicespecifieke foutafhandeling

Voor opslagservices zoals Blobs, Bestanden en Wachtrijen kunt u fouten afhandelen op basis van zowel foutcodes als HTTP-statuscodes:

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;
    }
}

Voor Key Vault-bewerkingen moet u mogelijk afzonderlijke verificatie-uitzonderingen afhandelen:

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
}

Overwegingen van threadveiligheid

De Azure SDK voor C++ garandeert dat clientinstantiemethoden thread-veilig en onafhankelijk van elkaar zijn. Dit betekent dat u een clientinstantie veilig over meerdere threads kunt gebruiken zonder dat synchronisatie nodig is.

Houd rekening met het volgende bij het verwerken van uitzonderingen in threads:

  1. Uitzonderingsobjecten mogen niet worden gedeeld tussen threads, tenzij correct gesynchroniseerd
  2. De RequestFailedException bevat een kopieerconstructor waarmee een diepe kopie wordt gemaakt, die kan worden gebruikt wanneer u uitzonderingsinformatie tussen threads moet doorgeven