restsharp / RestSharp

Simple REST and HTTP API Client for .NET
https://restsharp.dev
Apache License 2.0
9.63k stars 2.34k forks source link

RestSharp throws an exception if the HTTP request returns UNAUTHORIZED #2269

Closed seannybgoode closed 1 month ago

seannybgoode commented 1 month ago

Describe the bug Restsharp is throwing an exception when a request returns unauthorized. This is a naive interpretation of the behavior. No standard HTTP response should throw an exception, it should be up to the end-user to handle the exception. In my particular use-case, I need information from the REST response in-order to construct a properly formatted 2nd attempt. This is new behavior, and the library did not previously behave in this manner when a response returned unauthorized.

To Reproduce Create a rest-request with basic authorization that will return a 403 unauthorized.

Expected behavior The library should not throw an exception, and let me handle the unauthorized response with a fully populated RestResponse object.

Call Stack [2024-10-21T23:57:38.870Z] Error occurred while running the function: Request failed with status code Unauthorized /n at RestSharp.ResponseThrowExtension.ThrowIfError(RestResponse response) [2024-10-21T23:57:38.874Z] at RestSharp.RestClientExtensions.GetAsync(IRestClient client, RestRequest request, CancellationToken cancellationToken) [2024-10-21T23:57:38.877Z] at RestSharp.AsyncHelpers.<>cDisplayClass1_01.<<RunSync>b__0>d.MoveNext() [2024-10-21T23:57:38.880Z] --- End of stack trace from previous location --- [2024-10-21T23:57:38.884Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.<Run>g__PostCallback|7_0(Object _) [2024-10-21T23:57:38.887Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.Run() [2024-10-21T23:57:38.888Z] at RestSharp.AsyncHelpers.RunSync(Func1 task) [2024-10-21T23:57:38.889Z] at RestSharp.AsyncHelpers.RunSync[T](Func1 task) [2024-10-21T23:57:38.889Z] at RestSharp.RestClientExtensions.Get(IRestClient client, RestRequest request) [2024-10-21T23:57:38.890Z] at SeniorityAdapterV2.WeeklyStateCapture.Run(TimerInfo myTimer) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\WeeklyStateCapture.cs:line 85 [2024-10-21T23:57:38.999Z] Function 'WeeklyStateCapture', Invocation id 'b24bddc4-d9bb-45a6-bab9-6b4388fa1f46': An exception was thrown by the invocation. [2024-10-21T23:57:39.002Z] Result: Function 'WeeklyStateCapture', Invocation id 'b24bddc4-d9bb-45a6-bab9-6b4388fa1f46': An exception was thrown by the invocation. Exception: System.Net.Http.HttpRequestException: Request failed with status code Unauthorized [2024-10-21T23:57:39.004Z] at RestSharp.ResponseThrowExtension.ThrowIfError(RestResponse response) [2024-10-21T23:57:39.005Z] at RestSharp.RestClientExtensions.GetAsync(IRestClient client, RestRequest request, CancellationToken cancellationToken) [2024-10-21T23:57:39.006Z] at RestSharp.AsyncHelpers.<>c__DisplayClass1_01.<b0>d.MoveNext() [2024-10-21T23:57:39.007Z] --- End of stack trace from previous location --- [2024-10-21T23:57:39.008Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.gPostCallback|70(Object ) [2024-10-21T23:57:39.009Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.Run() [2024-10-21T23:57:39.009Z] at RestSharp.AsyncHelpers.RunSync(Func1 task) [2024-10-21T23:57:39.010Z] at RestSharp.AsyncHelpers.RunSync[T](Func1 task) [2024-10-21T23:57:39.013Z] at RestSharp.RestClientExtensions.Get(IRestClient client, RestRequest request) [2024-10-21T23:57:39.014Z] at SeniorityAdapterV2.WeeklyStateCapture.Run(TimerInfo myTimer) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\WeeklyStateCapture.cs:line 85 [2024-10-21T23:57:39.015Z] at SeniorityAdapter_V2.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 38 [2024-10-21T23:57:39.016Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13 [2024-10-21T23:57:39.017Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 38 [2024-10-21T23:57:39.018Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91 Stack: at RestSharp.ResponseThrowExtension.ThrowIfError(RestResponse response) [2024-10-21T23:57:39.019Z] at RestSharp.RestClientExtensions.GetAsync(IRestClient client, RestRequest request, CancellationToken cancellationToken) [2024-10-21T23:57:39.020Z] at RestSharp.AsyncHelpers.<>cDisplayClass1_01.<<RunSync>b__0>d.MoveNext() [2024-10-21T23:57:39.020Z] --- End of stack trace from previous location --- [2024-10-21T23:57:39.021Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.<Run>g__PostCallback|7_0(Object _) [2024-10-21T23:57:39.022Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.Run() [2024-10-21T23:57:39.022Z] at RestSharp.AsyncHelpers.RunSync(Func1 task) [2024-10-21T23:57:39.023Z] at RestSharp.AsyncHelpers.RunSync[T](Func1 task) [2024-10-21T23:57:39.024Z] at RestSharp.RestClientExtensions.Get(IRestClient client, RestRequest request) [2024-10-21T23:57:39.028Z] at SeniorityAdapterV2.WeeklyStateCapture.Run(TimerInfo myTimer) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\WeeklyStateCapture.cs:line 85 [2024-10-21T23:57:39.029Z] at SeniorityAdapter_V2.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 38 [2024-10-21T23:57:39.030Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13 [2024-10-21T23:57:39.031Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 38 [2024-10-21T23:57:39.032Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91. [2024-10-21T23:57:39.090Z] Executed 'Functions.WeeklyStateCapture' (Failed, Id=b24bddc4-d9bb-45a6-bab9-6b4388fa1f46, Duration=281605ms) [2024-10-21T23:57:39.093Z] System.Private.CoreLib: Exception while executing function: Functions.WeeklyStateCapture. System.Private.CoreLib: Result: Failure Exception: System.Net.Http.HttpRequestException: Request failed with status code Unauthorized [2024-10-21T23:57:39.095Z] at RestSharp.ResponseThrowExtension.ThrowIfError(RestResponse response) [2024-10-21T23:57:39.095Z] at RestSharp.RestClientExtensions.GetAsync(IRestClient client, RestRequest request, CancellationToken cancellationToken) [2024-10-21T23:57:39.096Z] at RestSharp.AsyncHelpers.<>c__DisplayClass1_01.<b0>d.MoveNext() [2024-10-21T23:57:39.097Z] --- End of stack trace from previous location --- [2024-10-21T23:57:39.098Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.gPostCallback|70(Object ) [2024-10-21T23:57:39.098Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.Run() [2024-10-21T23:57:39.099Z] at RestSharp.AsyncHelpers.RunSync(Func1 task) [2024-10-21T23:57:39.100Z] at RestSharp.AsyncHelpers.RunSync[T](Func1 task) [2024-10-21T23:57:39.101Z] at RestSharp.RestClientExtensions.Get(IRestClient client, RestRequest request) [2024-10-21T23:57:39.101Z] at SeniorityAdapterV2.WeeklyStateCapture.Run(TimerInfo myTimer) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\WeeklyStateCapture.cs:line 85 [2024-10-21T23:57:39.102Z] at SeniorityAdapter_V2.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 38 [2024-10-21T23:57:39.105Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13 [2024-10-21T23:57:39.106Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 38 [2024-10-21T23:57:39.107Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91 [2024-10-21T23:57:39.108Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 Stack: at RestSharp.ResponseThrowExtension.ThrowIfError(RestResponse response) [2024-10-21T23:57:39.109Z] at RestSharp.RestClientExtensions.GetAsync(IRestClient client, RestRequest request, CancellationToken cancellationToken) [2024-10-21T23:57:39.110Z] at RestSharp.AsyncHelpers.<>c__DisplayClass1_01.<<RunSync>b__0>d.MoveNext() [2024-10-21T23:57:39.111Z] --- End of stack trace from previous location --- [2024-10-21T23:57:39.111Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.<Run>g__PostCallback|7_0(Object _) [2024-10-21T23:57:39.112Z] at RestSharp.AsyncHelpers.CustomSynchronizationContext.Run() [2024-10-21T23:57:39.113Z] at RestSharp.AsyncHelpers.RunSync(Func1 task) [2024-10-21T23:57:39.114Z] at RestSharp.AsyncHelpers.RunSync[T](Func`1 task) [2024-10-21T23:57:39.114Z] at RestSharp.RestClientExtensions.Get(IRestClient client, RestRequest request) [2024-10-21T23:57:39.115Z] at SeniorityAdapterV2.WeeklyStateCapture.Run(TimerInfo myTimer) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\WeeklyStateCapture.cs:line 85 [2024-10-21T23:57:39.117Z] at SeniorityAdapter_V2.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\sbrophy\Source\Repos\SeniorityAdapter_V2\SeniorityAdapter_V2\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 38 [2024-10-21T23:57:39.118Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13 [2024-10-21T23:57:39.118Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 38 [2024-10-21T23:57:39.121Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91 [2024-10-21T23:57:39.122Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88.

Desktop (please complete the following information):

Additional context ThrowOnAnyError is set to false.

I require the response URL because I need to know where the initial request was redirected, in order to properly format the correct response. This is because the service developer updates the URL subnet every single time they release an update, which would otherwise require me to release an update every time they do. With my approach, my code will work out their new subnet automatically.

faddeyca commented 1 month ago

Hello! This library is designed to throw an exception if you use Get. Please use client.Execute(request) to get the RestResponse object without throwing exceptions.

alexeyzimarev commented 1 month ago

https://restsharp.dev/docs/advanced/error-handling