Handling Errors with the .NET SDK

    +
    Common errors and exceptions, and how to handle them.

    Errors are inevitable. The developer’s job is to be prepared for whatever is likely to come up — and to try and be prepared for anything that conceivably could come up. Couchbase gives you a lot of flexibility, but it is recommended that you equip yourself with an understanding of the possibilities.

    How the SDK Handles Errors

    Couchbase-specific exceptions are all derived from CouchbaseException. Errors that cannot be recovered by the SDK will be returned to the application. These unrecoverable errors are left to the application developer to handle — this section covers handling many of the common error scenarios.

    Handling Errors

    The approach will depend upon the type of error thrown. Is it transient? Is it even recoverable? Below we examine error handling strategies in relation to the Couchbase SDKs, then take a practical walk through some common error scenarios you are likely to have to handle when working with a Couchbase cluster.

    Logging

    It is always important to log errors, but even more so with highly concurrent asynchronous applications.

    Retry

    Transient errors — such as those caused by resource starvation — are best tackled with one of the following retry strategies:

    • Retry immediately.

    • Retry with a fixed delay.

    • Retry with a linearly increasing delay.

    • Retry with an exponentially increasing delay.

    • Retry with a random delay.

    var attempts = MaxRetries; // eg 5
    while (attempts-- > 0)
    {
        // will throw KeyNotfoundException if key doesn't exist
        var document = await collection.GetAsync("doc_id");
        var user = document.ContentAs<User>();
        user.Email = "john.smith@couchbase.com";
    
        try
        {
            await collection.ReplaceAsync("doc_id", user);
    
            // replace succeeded, break from loop
            break;
        }
        catch (CouchbaseException exception)
        {
            switch (exception)
            {
                // unrecoverable error (network failure, etc)
                case NetworkErrorException _:
                    throw;
    
                //case other unrecoverable exceptions
            }
        }
    
        // wait 100 milliseconds before trying again
        Task.Delay(100);
    }

    KV

    The KV Service exposes several common errors that can be encountered - both during development, and to be handled by the production app. Here we will cover some of the most common errors.

    Key does not exist

    try
    {
        await collection.ReplaceAsync("my-key", new { });
    }
    catch (KeyNotFoundException)
    {
        // key does not exist
    }

    Key already exists

    try
    {
        await collection.InsertAsync("my-key", new { });
    }
    catch (KeyExistsException)
    {
        // key already exists
    }

    Document body too large

    try
    {
    	await collection.InsertAsync("my-key", myReallyLargeObject);
    }
    catch (ValueTooLargeException)
    {
    	  // document body is too large
    }

    CAS Mismatch

    try
    {
        var result = await collection.GetAsync("my-key");
        await collection.ReplaceAsync("my-key", new { }, options => options.WithCas(result.Cas));
    }
    catch (CasMismatchException)
    {
        // the CAS value has changed
    }