Intermittent ExchangeException when getting EWS mail folders using GetEWSClient in Aspose.Email

320 Views Asked by At

I have a Windows service that uses Aspose.Email to call Exchange365 using EWS to read the list of mailbox folders, select a folder and then read the messages. I'm using OAuth Client Credentials authentication.

It works great most of the time but intermittently (around 1-2% of calls) I get an error like this:

ExchangeException: An internal server error occurred. The operation failed.
   at #=zJwR5hYhASPjEG51KcFP5cfaNW_E9xKzbKNrDvkouRDML.#=zbEiudxU=(Exception #=zXBxojZA=)
   at #=zJwR5hYhASPjEG51KcFP5cfaNW_E9xKzbKNrDvkouRDML.#=zJxs8Enk=()
   at Aspose.Email.Clients.Exchange.WebService.EWSClient.#=zeKhM5WV7jZFJ(String #=zwl3m1OEGe_npeTCLKA==, ICredentials #=z8dcYagA=, WebProxy #=zPxR7k20=, #=zobHVK5XZznS2TuzCjFYVkWlb_06X8KyvTg== #=zuLDkIL8cyRRE, #=zLSBmP6s5p40Nd06_7HFvrX6K9S$RdU6i23eiqR0t6nn3VKSIig== #=zPNhWaZtYKy02YJZNn6uibe8=)
   at Aspose.Email.Clients.Exchange.WebService.EWSClient.GetEWSClient(String mailboxUri, ICredentials credentials, WebProxy proxy)
   at Aspose.Email.Clients.Exchange.WebService.EWSClient.GetEWSClient(String mailboxUri, ICredentials credentials)
   at EmailTest.Program.GetFolders(OAuthNetworkCredential credentials) in C:\Dev\Sandbox\EmailTest\Program.cs:line 72
   at EmailTest.Program.<Main>d__0.MoveNext() in C:\Dev\Sandbox\EmailTest\Program.cs:line 42

or

ExchangeException: An internal server error occurred. The operation failed.
   at #=zRSjcm9RrA3a6zmmitFu34UW3nW4gV823KL6N1k9mXXhY.#=zqfYcQSUW7xkI(WebException #=zMMH$jH0=)
   at #=zRSjcm9RrA3a6zmmitFu34UW3nW4gV823KL6N1k9mXXhY.GetResponse()
   at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
   at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at #=zKdOmVOFQs9ARtLG3Zlu_IvXd08LXFmI3_5D9s_gr4KsZjsevGw==.FindFolder(FindFolderType FindFolder1)
   at #=zKdOmVOFQs9ARtLG3Zlu_ImWGLEjOliBGtOJU8_WNO6d9X7U9LuJoRwA=.#=zthDK7XA=(BaseFolderIdType #=zW0dJQvKwqFVf, String #=z7p_vI0c=)
   at #=zKdOmVOFQs9ARtLG3Zlu_ImWGLEjOliBGtOJU8_WNO6d9X7U9LuJoRwA=.#=zthDK7XA=(String #=zxohf2Vezm7Vf, String #=z$vyJZib10Ez_, String #=z7p_vI0c=)
   at #=zTAbjhrGUH9E0n8cOeUNrQiqgnbUhJNI_gUj7wuZ$HYDp.ListSubFolders(String #=zxohf2Vezm7Vf, String #=znaKuRg4Rx3vw)
   at #=zTAbjhrGUH9E0n8cOeUNrQiqgnbUhJNI_gUj7wuZ$HYDp.ListSubFolders(String #=znaKuRg4Rx3vw)
   at EmailTest.Program.GetFolders(OAuthNetworkCredential credentials) in C:\Dev\Sandbox\EmailTest\Program.cs:line 74
   at EmailTest.Program.<Main>d__0.MoveNext() in C:\Dev\Sandbox\EmailTest\Program.cs:line 42

If I retry the failing call immediately afterwards, it works fine. So as a workaround I use a "retry" pattern with this call, but I don't like this and I want to know why it's failing. I made a cut-down version of my code for investigation purposes.

Here is how I'm creating the credentials:

private static async Task<OAuthNetworkCredential> GetAccessTokenWithClientCredentials()
{
    var app = ConfidentialClientApplicationBuilder
        .Create(Settings.ClientId)
        .WithTenantId(Settings.TenantId)
        .WithClientSecret(Settings.ClientSecret)
        .Build();

    AuthenticationResult authResult =
        await app.AcquireTokenForClient(new[] { Settings.Scopes }).ExecuteAsync().ConfigureAwait(false);
    return new OAuthNetworkCredential(Settings.Username, authResult.AccessToken);
}

and here's how I'm calling the folders:

private static string GetFolders(OAuthNetworkCredential credentials)
{
    using (IEWSClient client = EWSClient.GetEWSClient(Settings.ExchangeWSUrl, credentials))
    {
        ExchangeFolderInfoCollection folders = client.ListSubFolders(client.MailboxInfo.RootUri);
        return string.Join(", ", folders.Select(x => x.DisplayName));
    }
}

This is using Aspose.Email 22.8 and Microsoft.Identity.Client 4.46.2.
ExchangeWSUrl is https://outlook.office365.com/ews/exchange.asmx
Scopes is https://outlook.office.com/.default

2

There are 2 best solutions below

0
On

Update: I haven't changed my code or version of Aspose at all, and the exception doesn't occur anymore.

My feeling is that Microsoft have changed something on the Exchange side to fix the issue, so happy days.

1
On

If your using the client_credentails flow you need to be using Impersonation and you should be setting the X-AnchorMailbox header to the mailbox you impersonating (I don't use apose but they have an example of it in their docs https://docs.aspose.com/email/net/utility-features/). This affect how a request is routed, that said mailboxes move around in the cloud often so availability is not always guaranteed and you should always expect some requests will fail if the mailbox is being moved.