I'm experiencing an issue with incorrect line numbers being reported in the call stack from Azure Application Insights in our .NET 6.0 production environment. The problem seems to be inconsistent and occurs in multiple places throughout our codebase.
Here's an example of the issue:
System.NullReferenceException:
at LEA.Novo.Services.Packages.ProductSupply.ProductSupplyPackageFlowService.ApplyStepOrder (LEA.Novo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\source\backend\Customers\Novonordisk\LEA.Novo\Services\Package\ProductSupply\ProductSupplyPackageFlowService.cs:679)
at LEA.Novo.Services.Packages.ProductSupply.ProductSupplyPackageFlowService+<RefreshPackageFlow>d__12.MoveNext (LEA.Novo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\source\backend\Customers\Novonordisk\LEA.Novo\Services\Package\ProductSupply\ProductSupplyPackageFlowService.cs:100)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at LEA.WebApi.Controllers.PackageControllers.PackageFlowController+<RefreshPackageFlow>d__4.MoveNext (LEA.WebApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\source\backend\LEA\LEA.WebApi\Controllers\PackageControllers\PackageFlowController.cs:46)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at lambda_method24673 (Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+AwaitableObjectResultExecutor+<Execute>d__0.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker+<<InvokeActionMethodAsync>g__Logged|12_1>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker+<<InvokeNextActionFilterAsync>g__Awaited|10_0>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker+<<InvokeInnerFilterAsync>g__Awaited|13_0>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<<InvokeNextResourceFilter>g__Awaited|25_0>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<<InvokeFilterPipelineAsync>g__Awaited|20_0>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<<InvokeAsync>g__Logged|17_1>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker+<<InvokeAsync>g__Logged|17_1>d.MoveNext (Microsoft.AspNetCore.Mvc.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Routing.EndpointMiddleware+<<Invoke>g__AwaitRequestTask|6_0>d.MoveNext (Microsoft.AspNetCore.Routing, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler+<HandleAsync>d__0.MoveNext (Microsoft.AspNetCore.Authorization.Policy, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware+<Invoke>d__6.MoveNext (Microsoft.AspNetCore.Authorization.Policy, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at LEA.Middleware.MW00_ExceptionHandler+<Invoke>d__3.MoveNext (LEA.WebApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\source\backend\LEA\LEA.WebApi\Middleware\MW00_ExceptionHandler.cs:32)
In this example, ProductSupplyPackageFlowService.cs:100
appears to be correct, but there's no logical reason for the exception to occur on ProductSupplyPackageFlowService.cs:679
(please refer to the two screenshots for more information. This discrepancy in line numbers is not isolated to this specific case and has been observed in other parts of the application as well.
Questions:
Any insights or suggestions would be greatly appreciated. Thank you!
Tried to check by disabling C# JIT optimization did not help.
var grouped = updated.GroupBy(u => u.PackageId);
foreach (var group in grouped)
{
var package = packages
.Where(p => p.Id == group.Key)
.SingleOrThrowNotFound();
var packageProperties = await _packageService.GetPackageProperties(package.PackagePropertyIds);
var launchSpeedProperty = packageProperties.FirstOrDefault(prop => prop.PackagePropertyTypeId == launchSpeed?.Id);
var launchTypeProperty = packageProperties.FirstOrDefault(prop => prop.PackagePropertyTypeId == launchType?.Id);
var itemTypeProperty = packageProperties.FirstOrDefault(prop => prop.PackagePropertyTypeId == itemType?.Id);
var inputNumber = new ProductSupplyRefreshInput(launchSpeedProperty?.Number,
launchTypeProperty?.Number,
itemTypeProperty?.Number);
var allSteps = CreatePackageSteps();
////Set step order
ApplyStepOrder(allSteps, launchTypeProperty);
var packagePropertyIds = new ProductSupplyRefreshInput(packageProperties.FirstOrDefault(prop => prop.PackagePropertyTypeId == launchSpeed?.Id)?.Id,
packageProperties.FirstOrDefault(prop => prop.PackagePropertyTypeId == launchType?.Id)?.Id,
packageProperties.FirstOrDefault(prop => prop.PackagePropertyTypeId == itemType?.Id)?.Id);
//Set lead time
await ApplyLeadTime(allSteps, packageStepTypes, launchSpeed, launchType, itemType, packagePropertyIds);
var _steps = group;
////Merge available steps into basic package flow
MergePackageSteps(allSteps, _steps, packageStepTypes);
//If 'Standard launch' then update action date based on launch date input
if (inputNumber.LaunchSpeed.HasValue && inputNumber.LaunchSpeed.Value == LaunchSpeed.StandardLaunch.PackageType)
{
await CalculationActionDate(allSteps, meta, inputNumber, launchTypeProperty);
// For standard launch, calculation should start from Action Date
var actionDateStep = allSteps.Single(a => a.PackageStepType == ProductSupplyPackageStepType.ActionDate);
actionDateStep.ClearPreSteps();
}
// Refresh package flow by starting from HA approval date
var startStep = allSteps.Single(a => a.PackageStepType == ProductSupplyPackageStepType.HaApproval);
//Apply Is Milestone
foreach(var step in allSteps)
{
step.IsMilestone = packageStepTypes.Single(pst => pst.Number == (int)step.PackageStepType).IsMilestone;
step.EndDateIsAuto = step.IsMilestone || step.EndDateIsAuto;
}
await CalculateDates(allSteps, startStep, ProductSupplyFlowCalculationDirection.Forward, meta, inputNumber);
//Calculate fixed PA date
var paDate = await CalculateStepsBackwardsDate(ProductSupplyPackageStepType.ProductAvailability, allSteps, meta, inputNumber, launchTypeProperty);
var paStep = allSteps.Single(a => a.PackageStepType == ProductSupplyPackageStepType.ProductAvailability);
if (paDate.HasValue && paStep.StartDateIsAuto)
{
paStep.StartDate = paDate;
}
// TODO: Need to fix Status and Step Type
result.AddRange(allSteps.Select(s => new PackageStepDTO()
{
PackageId = group.Key,
PackageStepStatusId = s.PackageStepStatusId,
PackageStepTypeId = packageStepTypes.FirstOrDefault(pst => pst.Number == (int)s.PackageStepType)?.Id ?? 0,
CompletionDate = s.CompletionDate,
CompletionDateIsAuto = true, //Always true for NN
EndDate = s.EndDate,
EndDateIsAuto = s.EndDateIsAuto,
StartDate = s.StartDate,
StartDateIsAuto = s.StartDateIsAuto,
IsActive = s.IsActive,
ResponsibleUserId = s.ResponsibleUserId,
Duration = IsStepWithManualDuration(s.PackageStepType) ? (int?)s.DurationWorkingDays : null
}));
await CalculatePackageWarning(package, allSteps, packageWarnings);
CalculatePackageStepStatus(result, packageStepTypes, package);
CalculatePackageStatus(package, packageStepTypes, result);
}
private void ApplyStepOrder(IEnumerable<TemporaryPackageStep> steps, PackagePropertyDTO launchType)
{
if (launchType.Code == "LM") // Local manufacturing
{
AddStepNavigation(steps, ProductSupplyPackageStepType.HaApproval, ProductSupplyPackageStepType.ActionDate);
AddStepNavigation(steps, ProductSupplyPackageStepType.ActionDate, ProductSupplyPackageStepType.RIMS);
AddStepNavigation(steps, ProductSupplyPackageStepType.ActionDate, ProductSupplyPackageStepType.RALabel);
AddStepNavigation(steps, ProductSupplyPackageStepType.RALabel, ProductSupplyPackageStepType.SoOp);
AddStepNavigation(steps, ProductSupplyPackageStepType.RIMS, ProductSupplyPackageStepType.RABom);
AddStepNavigation(steps, ProductSupplyPackageStepType.SoOp, ProductSupplyPackageStepType.ReadyToShip);
AddStepNavigation(steps, ProductSupplyPackageStepType.RABom, ProductSupplyPackageStepType.ReadyToShip);
AddStepNavigation(steps, ProductSupplyPackageStepType.ReadyToShip, ProductSupplyPackageStepType.LD);
AddStepNavigation(steps, ProductSupplyPackageStepType.LD, ProductSupplyPackageStepType.ProductAvailability);
AddStepNavigation(steps, ProductSupplyPackageStepType.ProductAvailability, ProductSupplyPackageStepType.PackQA);
AddStepNavigation(steps, ProductSupplyPackageStepType.PackQA, ProductSupplyPackageStepType.LocalHandling);
AddStepNavigation(steps, ProductSupplyPackageStepType.LocalHandling, ProductSupplyPackageStepType.Launch);
}
else if (launchType.Code == "Dialoq") // Dialoq flow
{
AddStepNavigation(steps, ProductSupplyPackageStepType.HaApproval, ProductSupplyPackageStepType.ActionDate);
AddStepNavigation(steps, ProductSupplyPackageStepType.ActionDate, ProductSupplyPackageStepType.RIMS);
AddStepNavigation(steps, ProductSupplyPackageStepType.ActionDate, ProductSupplyPackageStepType.RALabel);
AddStepNavigation(steps, ProductSupplyPackageStepType.RIMS, ProductSupplyPackageStepType.PackQA);
AddStepNavigation(steps, ProductSupplyPackageStepType.RALabel, ProductSupplyPackageStepType.RABom);
AddStepNavigation(steps, ProductSupplyPackageStepType.RABom, ProductSupplyPackageStepType.SoOp);
AddStepNavigation(steps, ProductSupplyPackageStepType.SoOp, ProductSupplyPackageStepType.PackQA);
AddStepNavigation(steps, ProductSupplyPackageStepType.PackQA, ProductSupplyPackageStepType.ReadyToShip);
AddStepNavigation(steps, ProductSupplyPackageStepType.ReadyToShip, ProductSupplyPackageStepType.LD);
AddStepNavigation(steps, ProductSupplyPackageStepType.LD, ProductSupplyPackageStepType.ProductAvailability);
AddStepNavigation(steps, ProductSupplyPackageStepType.ProductAvailability, ProductSupplyPackageStepType.LocalHandling);
AddStepNavigation(steps, ProductSupplyPackageStepType.LocalHandling, ProductSupplyPackageStepType.Launch);
}
else
{
//Standard flow
AddStepNavigation(steps, ProductSupplyPackageStepType.HaApproval, ProductSupplyPackageStepType.ActionDate);
AddStepNavigation(steps, ProductSupplyPackageStepType.ActionDate, ProductSupplyPackageStepType.RIMS);
AddStepNavigation(steps, ProductSupplyPackageStepType.ActionDate, ProductSupplyPackageStepType.RALabel);
AddStepNavigation(steps, ProductSupplyPackageStepType.RALabel, ProductSupplyPackageStepType.SoOp);
AddStepNavigation(steps, ProductSupplyPackageStepType.RIMS, ProductSupplyPackageStepType.RABom);
AddStepNavigation(steps, ProductSupplyPackageStepType.SoOp, ProductSupplyPackageStepType.PackQA);
AddStepNavigation(steps, ProductSupplyPackageStepType.RABom, ProductSupplyPackageStepType.PackQA);
AddStepNavigation(steps, ProductSupplyPackageStepType.PackQA, ProductSupplyPackageStepType.ReadyToShip);
AddStepNavigation(steps, ProductSupplyPackageStepType.ReadyToShip, ProductSupplyPackageStepType.LD);
AddStepNavigation(steps, ProductSupplyPackageStepType.LD, ProductSupplyPackageStepType.ProductAvailability);
AddStepNavigation(steps, ProductSupplyPackageStepType.ProductAvailability, ProductSupplyPackageStepType.LocalHandling);
AddStepNavigation(steps, ProductSupplyPackageStepType.LocalHandling, ProductSupplyPackageStepType.Launch); /// Failing line
}
}
private void AddStepNavigation(IEnumerable<TemporaryPackageStep> steps, ProductSupplyPackageStepType from, ProductSupplyPackageStepType to)
{
var _from = GetStepByPackageStepType(steps, from);
var _to = GetStepByPackageStepType(steps, to);
if (_from == null || _to == null)
{
_logger.LogDebug("Step type is not found: From = " + from.ToString() + ", To = " + to.ToString() );
return;
}
_from.AddPost(_to);
}
First of all, it should not as there is a condition before that line that is checking for null and returning of _from or _to is null.
Then it should prevent null pointer exceptions from occurring inside the method. However, if an exception does happen within the method, it should be logged accurately, including capturing the method name in the call stack.
The AddStepNavigation
method checks for null references before proceeding. If a null reference is found, it logs the issue and returns without further processing.
Check that exceptions are logged correctly and that the method name and stack trace are included in the logs. This will help diagnose any issues accurately.
Revised Code:
private void AddStepNavigation(IEnumerable<TemporaryPackageStep> steps, ProductSupplyPackageStepType from, ProductSupplyPackageStepType to)
{
try
{
var _from = GetStepByPackageStepType(steps, from);
var _to = GetStepByPackageStepType(steps, to);
if (_from == null || _to == null)
{
// Log a warning if the steps are not found
_logger.LogWarning("Step type is not found: From = {From}, To = {To}", from, to);
return;
}
_from.AddPost(_to);
}
catch (Exception ex)
{
// Log the exception including the method name
_logger.LogError(ex, "Exception occurred in {MethodName} with From = {From} and To = {To}", nameof(AddStepNavigation), from, to);
// Send the exception details to Application Insights
_telemetryClient.TrackException(ex);
_telemetryClient.Flush();
}
}
try-catch
block is added to handle any unexpected exceptions within the AddStepNavigation
method and the LogError
method logs the exception, including the method name and parameters, ensuring the stack trace includes AddStepNavigation
..csproj
configuration generates portable PDB files and includes them in the release builds.
By this we can be able to capture and diagnose issues in the AddStepNavigation
method and other parts of your application.