4

I have the following defined in my Global.asax.vb...

Private Sub Global_asax_BeginRequest(sender As Object, e As EventArgs) Handles Me.BeginRequest
    Try
        If Request IsNot Nothing Then 'this line throws an exception...
            With Request
                ...

The error is ...

ERROR - Global_asax:System.NullReferenceException: Object reference not set to an instance of an object.

I'm a bit confused as to how this particular line can error. All I'm trying to do is test to see if the object is null/Nothing.

I'm guessing there must be something else happening behind the scenes when the request begins, but I don't know how to debug it further.

This error doesn't occur every time. I'm just seeing these errors occasionally in the logs, and I don't know how they're occurring. I'm not able to reproduce it. Being unable to access the Request object, I can't get any other information about the type of request that causes it.

update...

I tried changing the way I access the Request property, to see if it would make any difference...

Public Sub Application_BeginRequest(sender As Object, e As EventArgs)
    Dim app As HttpApplication = TryCast(sender, HttpApplication)
    If app IsNot Nothing Then
        Dim _request = app.Request
...

This time, interestingly, the exception occurred at this line...

Dim app As HttpApplication = TryCast(sender, HttpApplication)

This seems very strange, as TryCast is specifically intended to not throw exceptions.

This is the full stack-trace I'm getting...

System.NullReferenceException: Object reference not set to an instance of an object.
     at Global_asax.Application_BeginRequest(Object sender, EventArgs e) in C:\vs_agent\_work\4\s\...\Global.asax.vb:line 97
     at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
     at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
     at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Line 97 corresponds to the TryCast line.

My current theory is that perhaps it has something to do with the Owin middleware

user1751825
  • 4,029
  • 1
  • 28
  • 58
  • 1
    Can you add stack trace and error details? Probably the `Request` you're using is not same as available `Request` property. Also the method name usually uses `Application_BeginRequest`, I never seen such like `Global_asax_BeginRequest`. – Tetsuya Yamamoto Nov 07 '18 at 04:23
  • As far as I can determine, it does the same thing, whether it's defined with the Handles Me.BeginRequest or as Application_BeginRequest. I can't seem to find any information about which way is preferable. In Visual Studio, if I get it to create the function stub for me, by clicking on "Global_asax Events" -> "BeginRequest", this is how it defines it. – user1751825 Nov 07 '18 at 04:56
  • I don't currently have the stacktrace in the logs for some reason. What I'm going to do, is add additional logging, and update here if I can get some more information. – user1751825 Nov 07 '18 at 04:57
  • @TetsuyaYamamoto I've just confirmed there is no stacktrace available. What I've included is all the detail I can get. I've tried changing to Application_BeginRequest, but the error remains exactly the same. Also, "Request" is just the standard Application property. There's no other "Request" from anywhere else in scope. – user1751825 Nov 07 '18 at 11:39
  • Did you experienced the error if you us the `Application_BeginRequest` or only in `Global_asax_BeginRequest`? Did you register the event correctly for the latter? – Gianpiero Nov 15 '18 at 15:04
  • @GianpieroCaretti The error was exactly the same whether I use Application_BeginRequest and Global_asax_BeginRequest – user1751825 Nov 15 '18 at 15:12
  • Have you ever installed URL Rewrite Extension ? – the_lotus Nov 15 '18 at 18:34
  • The rewrite extension has never been installed on these particular server instances. – user1751825 Nov 15 '18 at 22:31
  • I had that kind of issue once with a bug in the framework (due to the RyuJit compiler, that was fixed soon after). It happened only in release (with optimizations on) Make sure you have an updated version of .NET. – Simon Mourier Nov 17 '18 at 08:29
  • @user1751825 Did you managed to get a stack trace? What type of exception occurred this time, NullReferenceException? – Dipen Shah Nov 20 '18 at 20:10
  • @DipenShah Yes the exception is exactly the same as before. I'll update the the question with the stacktrace. – user1751825 Nov 20 '18 at 20:36
  • @user1751825 It would be hard to find out the exact case without the code. Would it be possible for you to generate MVP solution (post it on github) so that someone can reproduce the error? – Dipen Shah Nov 20 '18 at 20:42
  • @DipenShah I'm not sure what I would need to put in the sample solution to be able to demonstrate the problem. It only occurs in production, and seemingly randomly. I haven't been able to reproduce the issue myself in production, or any other environment. – user1751825 Nov 20 '18 at 22:59
  • @user1751825 I guess all packages and configuration, it doesn't need to have any web pages except for index. One more thing to look for is, IIS log in inetpub folder to find out request url when error occurred. – Dipen Shah Nov 21 '18 at 00:17
  • @DipenShah That's what's most confusing about it. It doesn't appear to coincide directly with any specific IIS requests. I can't find any direct correlation between the IIS request log, and these errors. It's almost as though something internally is triggering Application_BeginRequest, but doing it in some incorrect way. I'm not sure if it would be relevant or not, but the application also includes legacy classic ASP pages. – user1751825 Nov 21 '18 at 01:16
  • @user1751825 IMO, I don't think ASP pages has anything to do with this. However, can not say anything before actually seeing the code/error. Will it possible for you to generate dump file? Dump file will give you more detail about state of your app when the error occurs. This may help, https://stackoverflow.com/questions/1181536/how-to-create-a-dump-of-the-current-asp-net-managed-process-for-debugging – Dipen Shah Nov 21 '18 at 02:05
  • @user1751825 Do you see anything unusual in windows event log for System/Application/IIS logs at the time of exception? – Dipen Shah Nov 21 '18 at 02:05

2 Answers2

1

The described situation does not seem to be possible (I'll explain later) and I would recommend a bit more bullet-proof diagnostics for example

Try
  Dim locReq As HttpRequest = Request
Catch ex As Exception
   'record Exception with the complete stack trace
    Throw
End Try 

and use a HttpRequest variable (locReq) instead of the Request property. The snippet also prevents changing the Request property return value.

Why I think that your assumptions are not possible:

It is not possible to get NullReference in the line

If Request IsNot Nothing ...

but it can come from depth of the Request property. Its (translated) source code is

Public Class HttpApplication
'...
    Public ReadOnly Property Request As HttpRequest
        Get
            Dim request As HttpRequest = Nothing
            If _context IsNot Nothing AndAlso
                 Not _hideRequestResponse Then request = _context.Request

            If request Is Nothing Then Throw New HttpException(SR.GetString(SR.Request_not_available))
            Return request
        End Get
    End Property

Here again is a property Request with (translated) source code

Public NotInheritable Class HttpContext
    '...
    Private _response As HttpResponse
    '...
    Public ReadOnly Property Response As HttpResponse
        Get
            If HideRequestResponse OrElse
               HasWebSocketRequestTransitionCompleted Then Throw New 
                  HttpException(SR.GetString(SR.Response_not_available))
            Return _response
        End Get
    End Property

When I read the code I see no space for a null reference but there can be a HttpException. So my conclusion is that the logging system wrongly records the line or the exception.

Please take a look at IIS7 Integrated mode: Request is not available in this context exception in Application_Start which is connected to the Response_not_available exception.

Edit

I have attempted to interpret the presented stack trace. My conclusion from the deepest procedure (ExecuteStep(IExecutionStep step, ref bool completedSynchronously) is that the exception can occur only in its catch block (translated with original comments).

Catch e As Exception
        [error] = e
        'Since we will leave the context later, we need to remember if we are impersonating
         'before we lose that info - VSWhidbey 494476

        If ImpersonationContext.CurrentThreadTokenExists Then
            e.Data(System.Web.Management.WebThreadInformation.IsImpersonatingKey) = String.Empty
        End If
        'This might force ThreadAbortException to be thrown
        'automatically, because we consumed an exception that was
        'hiding ThreadAbortException behind it

        If TypeOf e Is ThreadAbortException AndAlso ((Thread.CurrentThread.ThreadState And ThreadState.AbortRequested) = 0) Then
            [error] = Nothing
            'Response.End from a COM+ component that re-throws ThreadAbortException
            'It is not a real ThreadAbort
             'VSWhidbey 178556
            _stepManager.CompleteRequest()
        End If
    End Try 

From this it seems that the problem is realy connected with aborting a thread. My speculatiom is that _stepManager is nothing, but I have no idea why.

IvanH
  • 5,039
  • 14
  • 60
  • 81
  • I think the line number may be wrong in the stack-trace. I may try to run production for a little while with debug on, to try to figure out exactly where the error is occurring. – user1751825 Nov 20 '18 at 08:14
  • My theory about the line numbers was incorrect. This wasn't the problem. I turned off debugging, but the line numbers remained the same. I don't know yet how the exception occurs on this line, but the line numbers appear to be accurate. – user1751825 Nov 20 '18 at 20:00
  • @user1751825 I have updated the answer. But it is only quick interpretation of source code. – IvanH Nov 22 '18 at 09:40
  • While the issue still seems to occur, your answer has helped to get me closer to figuring it out. – user1751825 Nov 23 '18 at 01:11
0

Just in case this is helpful to someone else.

I've finally figured out how to re-produce the error. It happens if I make a call without the User-Agent header. Like so...

curl -v -H 'User-Agent:' "https://[my_domain]/"

The path for the request doesn't seem to make any difference.

I expect if I can find a way to block all requests without a user-agent, then hopefully this will fix the problem.

What I can't quite understand though, is why Request isn't available in Application_BeginRequest, but is available in Application_Error.

user1751825
  • 4,029
  • 1
  • 28
  • 58