.NET by Patrik

Designing a Clean Exception Surface for Reusable .NET Libraries

Issue

Libraries often expose many raw exceptions, depending on how internal HTTP or retry logic is implemented. This forces library consumers to guess which exceptions to catch and creates unstable behavior.

Cause

Exception strategy is not treated as part of the library’s public contract. Internal exceptions leak out, and any change in handlers or retry logic changes what callers experience.

Resolution

Define a clear exception boundary:

  1. Internally
    Catch relevant exceptions (HttpRequestException, timeout exceptions, retry exceptions).

  2. Log them
    Use the unified logging method.

  3. Expose only a custom exception
    Throw a single exception type, such as ServiceClientException, at the public boundary.

Code Example

catch (Exception ex)
{
    LogServiceException(ex);
    throw new ServiceClientException("Service request failed.", ex);
}

This approach creates a predictable public API, hides implementation details, and ensures your library remains stable even as the internal HTTP pipeline evolves.

Comments