Particular / NServiceBus

Build, version, and monitor better microservices with the most powerful service platform for .NET
https://particular.net/nservicebus/
Other
2.1k stars 647 forks source link

Endpoint hosted in WCF throws an ArgumentNullException when trying to write .diagnostics file #5287

Open HEskandari opened 6 years ago

HEskandari commented 6 years ago

This is a case where the endpoint is hosted in a WCF service with the following hosting information:

The endpoint fails to start with an AggregatedException that contains a ArgumentNullException. The error goes away if a custom startup directory with write permission for the ApplicationPoolIdentity is set. The following is the stack trace:

StackTrace System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null. Parameter name: path at System.IO.Directory.CreateDirectory(String path) at NServiceBus.HostStartupDiagnostics.BuildDefaultDiagnosticsWriter(ReadOnlySettings settings) at NServiceBus.HostStartupDiagnostics.GetDiagnosticsWriter(ReadOnlySettings settings) at NServiceBus.HostStartupDiagnostics.Setup(FeatureConfigurationContext context) at NServiceBus.Features.FeatureActivator.ActivateFeature(FeatureInfo featureInfo, List`1 featuresToActivate, IConfigureComponents container, PipelineSettings pipelineSettings, RoutingComponent routing, ReceiveConfiguration receiveConfiguration) at NServiceBus.Features.FeatureActivator.SetupFeatures(IConfigureComponents container, PipelineSettings pipelineSettings, RoutingComponent routing, ReceiveConfiguration receiveConfiguration) at NServiceBus.InitializableEndpoint.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at NServiceBus.Endpoint.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult() at PurchaseOrder.MessageHandler.<>c__DisplayClass1_0.<b__0>d.MoveNext() in C:\Temp\agent\_work\8\s\PurchaseOrder\MessageHandler.cs:line 27 --- End of inner exception stack trace --- at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.Wait() at PurchaseOrder.MessageHandler.Event() at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) ---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null. Parameter name: path at System.IO.Directory.CreateDirectory(String path) at NServiceBus.HostStartupDiagnostics.BuildDefaultDiagnosticsWriter(ReadOnlySettings settings) at NServiceBus.HostStartupDiagnostics.GetDiagnosticsWriter(ReadOnlySettings settings) at NServiceBus.HostStartupDiagnostics.Setup(FeatureConfigurationContext context) at NServiceBus.Features.FeatureActivator.ActivateFeature(FeatureInfo featureInfo, List`1 featuresToActivate, IConfigureComponents container, PipelineSettings pipelineSettings, RoutingComponent routing, ReceiveConfiguration receiveConfiguration) at NServiceBus.Features.FeatureActivator.SetupFeatures(IConfigureComponents container, PipelineSettings pipelineSettings, RoutingComponent routing, ReceiveConfiguration receiveConfiguration) at NServiceBus.InitializableEndpoint.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at NServiceBus.Endpoint.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult() at PurchaseOrder.MessageHandler.<>c__DisplayClass1_0.<<>b__0>d.MoveNext() in C:\Temp\agent\_work\8\s\PurchaseOrder\MessageHandler.cs:line 27<---.
svlach commented 6 years ago

This issue is different than #5117 in that this issue isn't about not being able to write to a directory. It seems to me that this issue has to do with trying to determine the current users' app_data directory. For this IIS application, the running user has no home directory, and therefore no app_data directory, and the Null exception is that the app_data information is null. (Before trying to write out to a directory)

Once I override the app_data, then NSB won't exception out if it can't write to that directory (fixed in #5117).

andreasohlund commented 6 years ago

So it seems that https://github.com/Particular/NServiceBus/blob/develop/src/NServiceBus.Core/Hosting/StartupDiagnostics/Host.cs#L9 is returning null instead of throwing?

andreasohlund commented 6 years ago

@svlach just wanted to confirm that you're not blocked by this right? (overriding the diagnostics path is a valid workaround)

svlach commented 6 years ago

Hi Andreas,

Thanks for the follow up… We are not blocked by this issue. We have a workaround with setting a diagnostics path manually.

Steven

On Nov 12, 2018, at 05:51, Andreas Öhlund notifications@github.com<mailto:notifications@github.com> wrote:

@svlachhttps://github.com/svlach just wanted to confirm that you're not blocked by this right? (overriding the diagnostics path is a valid workaround)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/Particular/NServiceBus/issues/5287#issuecomment-437852214, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AqaUyGDjBdmZLyKItmBSUdPRnehCdk3Mks5uuWC8gaJpZM4X5WEM.

andreasohlund commented 6 years ago

Looking at the code, the only thing that could potentially return null would be

https://github.com/Particular/NServiceBus/blob/develop/src/NServiceBus.Core/Hosting/StartupDiagnostics/Host.cs#L28

@Particular/nservicebus-maintainers should we consider adding a null check there and throw a better error?

bording commented 6 years ago

@andreasohlund I'd prefer to have a working repro demonstrating when/how that would be null before just adding checks around it.

andreasohlund commented 6 years ago

@svlach I tried to repro this with a plain vanilla WCF service that run with the default IIS appool but I get:

Detected running in a website and attempted to use HostingEnvironment.MapPath("~/App_Data/") to derive the logging path. Failed since path returned (C:\inetpub\wwwroot\App_Data) does not exist. Ensure this directory is created and restart the endpoint.

Do I need to lock something down further?