Felhantering i Azure SDK för C++

Felhantering i Azure SDK för C++ implementeras främst via C++-undantag. Den här metoden överensstämmer med C++-standardmetoder och möjliggör tydlig felrapportering och hantering i hela SDK:t. När ditt C++-program interagerar med Azure-tjänster kan åtgärder misslyckas av olika orsaker, till exempel autentiseringsproblem, otillgängliga tjänster, ogiltiga begäranden eller resursbegränsningar. SDK samlar in dessa fel som undantag som ger detaljerad information om felet.

Undantagshierarki

Grundläggande undantagstyper

Azure SDK för C++ använder en hierarki med undantagsklasser, där de viktigaste är:

  1. std::runtime_error – Det grundläggande C++-standardfelet som Azure-specifika undantag ärver från.

  2. Azure::Core::RequestFailedException – Härledd från std::runtime_errorär det här basfelet för alla azure-tjänstbegärandefel. Definierat i azure/core/exception.hppgenereras det här undantaget när en begäran till en Azure-tjänst misslyckas. Den innehåller:

    • HTTP-statuskod
    • Felkoder från tjänsten
    • Felmeddelanden
    • Begära ID:t för felsökning
    • Http-råsvaret
  3. Azure::Core::OperationCancelledException – Härledd från std::runtime_errorgenereras det här undantaget när en åtgärd avbryts, vanligtvis via ett kontextobjekt.

  4. Azure::Core::Http::TransportException – Härledd från Azure::Core::RequestFailedExceptiongenereras det här undantaget när det finns ett fel i HTTP-transportlagret, till exempel anslutningsfel.

  5. Azure::Core::Credentials::AuthenticationException – Härledd från std::exceptiongenereras det här undantaget när autentisering med Azure-tjänster misslyckas.

Tjänstspecifika undantagstyper

Olika Azure-tjänster utökar de grundläggande undantagstyperna för att tillhandahålla tjänstspecifik felinformation:

  1. Azure::Storage::StorageException – Utökar RequestFailedException med ytterligare lagringsspecifik information. Det här undantaget omfattar:

    • Lagringsspecifika felkoder
    • Ytterligare information i svarstexten
    • Information om den misslyckade lagringsåtgärden
  2. Azure::Messaging::EventHubs::EventHubsException – Ett undantag som är specifikt för Event Hubs-åtgärder. Den innehåller:

    • Felvillkor (symboliskt värde från AMQP (Advanced Message Queuing Protocol))
    • Felbeskrivning
    • Statuskod
    • Information om huruvida felet är tillfälligt

Felmeddelanden i undantagshantering

Klassen RequestFailedException innehåller omfattande information om tjänstfel:

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

Tjänstspecifika undantag kan lägga till extra fält. Lägger till exempel StorageException till 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 ... */
};

Mönster och exempel för undantagshantering

Använda felkoder

Tjänstfel innehåller ErrorCode värden som kan användas för att fatta beslut om hur fel ska hanteras. Här är ett exempel med Lagringstjänster:

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

Hantera grundläggande undantag

Grundläggande mönster för hantering av undantag i 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
}

Hantera tillfälliga fel

Vissa tjänster, till exempel Event Hubs, ger information om huruvida ett fel är tillfälligt, vilket möjliggör omprövningslogik:

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

SDK implementerar interna återförsöksprinciper för tillfälliga fel, men du vill hantera specifika fall i programkoden.

Tjänstspecifik felhantering

För lagringstjänster (blobar, filer, köer osv.) kan du hantera fel baserat på både felkoder och HTTP-statuskoder:

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

För Key Vault-åtgärder kan du behöva hantera autentiseringsfel separat:

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
}

Trådsäkerhetsöverväganden

Azure SDK för C++ garanterar att klientinstansmetoder är trådsäkra och oberoende av varandra. Det innebär att du på ett säkert sätt kan använda en klientinstans i flera trådar utan synkronisering.

När du hanterar undantag mellan trådar bör du tänka på:

  1. Undantagsobjekt ska inte delas mellan trådar om de inte synkroniseras korrekt
  2. RequestFailedException Innehåller en kopieringskonstruktor som skapar en djupkopia, som kan användas när du behöver skicka undantagsinformation mellan trådar