UseHeaderPropagation not recognized during debug run - c#

I'm working on adding propagation to HotChocolate GraphQL server but simply can't get it working.
I've configured my propagation in my ConfigureServices services.AddHeaderPropagation(o => o.Headers.Add("Authorization"));
I've added it to my httpClient: services.AddHttpClient(AssumptionManagement, c => c.BaseAddress = new Uri("http://localhost:19801")).AddHeaderPropagation();
I've added it in my Configure method:
app.UseHeaderPropagation();
Despite all this it still gives me the following error when I run the app in debug:
An unhandled exception of type System.InvalidOperationException occurred in System.Private.CoreLib.dll: The HeaderPropagationValues.Headers property has not been initialized.
Register the header propagation middleware by adding app.UseHeaderPropagation() in the Configure(...) method. Header propagation can only be used within the context of an HTTP request.'
Am I just not seeing something here or what am I doing wrong?

Related

Can't Migrate for the following reason

builder.Services.AddDbContext<AppDbContext>(x =>
{
x.UseSqlServer(builder.Configuration.GetConnectionString("SqlConnection"), option =>
{
option.MigrationsAssembly(Assembly.GetAssembly(typeof(AppDbContext)).GetName().Name);
});
});
System.InvalidOperationException: 'Cannot modify ServiceCollection after application is built.'
When I run the program I get the above error.
However, when trying to migrate, I get the following error
Unable to create an object of type 'AppDbContext'.
It looks like your adding this after builder.Build() has been called, difficult to see without the full code.
Can you try moving it before?

How to log something before retry using Polly?

I'm attempting to log something before retrying a web api call using Polly in a .net core web api.
I know the web api is failing and returning a 503 response code however there's nothing in my console log as part of the retry call. Any ideas why and how to resolve this?
var retryPolicy = Policy
.Handle<HttpRequestException>()
.Or<SocketException>()
.WaitAndRetryAsync(new[]
{
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(10)
}, (exception, timeSpan, retryCount, context) =>
{
Console.Write("RETRYING - " + DateTime.Now.Second);
});
await retryPolicy.ExecuteAsync(async () =>
{
var serviceReturnLabel = await this.stockTransfersServiceClient.GetPRReturnLabel(ItemSourceType.ReturnLocker);
if (serviceReturnLabel != null && serviceReturnLabel.Accepted)
{
returnLabel = serviceReturnLabel.PRLabel;
}
});
The retry policy exposes a hook where you can wire up a custom code which will be called before the retry penalty. In other words this delegate will be called whenever the policy should be triggered but before the wait between the two attempts.
This hook is called onRetry or onRetryAsync depending whether your policy is sync or async respectively.
Here you can see when will these user defined custom delegates be called:
Sync Retry Policy
Async Retry Policy
So, you have wired up to the right hook.
Now you have to make sure that policy is triggered. You can use Console.Write or some logger to push information from your delegate to the standard output.
Or you can simply set a breakpoint in your anonymous lambda delegate to make sure that it is called during debugging.
If it is not called then you have to check the following:
Are the thrown exception handled?
Is there any exception at all?
From a policy perspective there can be two kinds of exceptions: handled and unhandled. The former can trigger a new attempt if the threshold is not reached yet. The latter won't trigger another attempt rather it will re-throw the original exception. (Reference)
In your case the policy has been setup to trigger either when a HttpRequestException is thrown or when a SocketException. If the thrown exception is none of these then it is considered unhandled from the policy perspective.
Your policy won't be triggered if there was no exception. There is one typical mistake that we have made several times. Let's suppose we expect that the http response should be 200. Whenever is not success then we want to issue a retry. We might utilize the HandleTransientHttpError (Ref) extension. But that extension watches only the 408 and 5xx status codes. So if we receive for example 429 (too many requests) then no retry will happen. We have to explicitly call the EnsureSuccessStatusCode (Ref) method to throw error if the response was not successful.

Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseSqlServer' call on ASP.NET core 2.2

I'm using aspnetboilerplate solution developed with ASP.NET core 2.2 . The backend is deployed on azure and it uses the SQL server provided.
Sometimes, when the backend has a lot of requests to handle, it logs this exception:
Mvc.ExceptionHandling.AbpExceptionFilter - An exception has been
raised that is likely due to a transient failure. Consider enabling
transient error resiliency by adding 'EnableRetryOnFailure()' to the
'UseSqlServer' call. System.InvalidOperationException: An exception
has been raised that is likely due to a transient failure. Consider
enabling transient error resiliency by adding 'EnableRetryOnFailure()'
to the 'UseSqlServer' call. ---> System.Data.SqlClient.SqlException: A
transport-level error has occurred when receiving results from the
serv
I tried to solve this problem adding this code to my Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// MVC
services.AddMvc(
options => options.Filters.Add(new CorsAuthorizationFilterFactory(_defaultCorsPolicyName))
).AddJsonOptions(
// To fix OldContract in Contract entity (self-referencing loop)
services.AddDbContext<ManagerDbContext>(options =>
{
options.UseSqlServer(_appConfiguration["ConnectionStrings:Default"],
sqlServerOptionsAction: builder =>
{
builder.EnableRetryOnFailure(
maxRetryCount: 10,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
});
});
}
But the problem is not solved.
you will have to add your error code in the list errorNumbersToAdd:
options.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(10),
errorNumbersToAdd: new List<int> { Add your code here});

Is it possible to change the value returned by Server.GetLastError()?

I have written an HttpModule for ASP.NET which will inspect the current exception (if any) and wrap it in a new exception with a unique identifier. Then I want Elmah to log that wrapping exception.
My module is working and is sitting in front of the Elmah module, however I can't work out how to change the Server.GetLastError() so that my new exception will be logged!
I have tried:
var originalException = context.Server.GetLastError();
var app = (HttpApplication)sender;
var context = app.Context;
context.ClearError();
context.AddError(new WrapperException(originalException));
But doing so makes the context.Error property return null.
In fact ClearError doesn't do what it's advertised to do: "Clears all errors for the current HTTP request."
It doesn't do this. The AllErrors array still contains exceptions; all it does make GetLastError return null.
You cannot set context.AllErrors, nor poke something into the array (it's a copy).
You also cannot throw a new exception: the error page only sees the original exception, and Elmah doesn't even log it.
I'm beginning to think that it's not possible.
If the only reason you want to replace Server.GetLastError() is to make sure that ELMAH logs the right exceptions, there may be a better approach. ELMAH's filtering feature can be used to override the logged exception. To do so, add the following code to your Global.asax.cs file:
void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs args)
{
var httpContext = args.Context as HttpContext;
ErrorLog.GetDefault(httpContext).Log(new Error(new WrapperException(args.Exception)));
args.Dismiss();
}
The ErrorLog_Filtering method is called by ELMAH just before logging any uncaught exceptions to the configured error log. In the example, I pull the information about the error happening (args.Context and args.Exception) and wrap the thrown exception in a new exception (WrapperException). By logging the new exception using the ErrorLog.GetDefault(...).Log(...) method, I make sure that ELMAH doesn't call the ErrorLog_Filtering method recursively (it would if you used ErrorSignal...Raise()). Finally, I dismiss the original exception, to avoid the error being logged twice.

Disable Owin Starup from code for some Controller

I am using Owin and Unity and on every request the startup config is being called and working as expected but if their is some database connection issue or some other exception I am handling that exception in Global.asax and redirecting to another controller but for now the problem is as the exception is in startup.cs while I a redirecting to my Error controller the startup is again getting called and I am getting the same exception again making a redirect loop. Is their any way to disable owin startup for one controller or something lie that.
Some Code
var uow = container.Resolve<IUnitOfWorkAsync>();
var cc = (ClaimCache)container.Resolve<IClaimCache>();
var cts = new HaiClaimsTransformationService(uow,cc);
var ctos = new HaiClaimsTransformationOptions(cts);
app.UseClaimsTransformation(ctos);

Categories