Within Application_Error, you actually can access ScriptManager to determine whether the current request is an asynchronous postback. The global object HttpContext.Current.Handler actually points to the page being serviced, which contains the ScriptManager object, which will tell you if the current request is asynchronous.
The following statement concisely illustrates how to access the ScriptManager object and get this information:
ScriptManager.GetCurrent(CType(HttpContext.Current.Handler, Page)).IsInAsyncPostBack
Of course, that statement will fail if the current request is not for a page, or if there is no ScriptManager on the current page, so here is a more robust pair of functions you can use inside Global.asax to make the determination:
Private Function GetCurrentScriptManager() As ScriptManager
'Attempts to get the script manager for the current page, if there is one
'Return nothing if the current request is not for a page
If Not TypeOf HttpContext.Current.Handler Is Page Then Return Nothing
'Get page
Dim p As Page = CType(HttpContext.Current.Handler, Page)
'Get ScriptManager (if there is one)
Dim sm As ScriptManager = ScriptManager.GetCurrent(p)
'Return the script manager (or nothing)
Return sm
End Function
Private Function IsInAsyncPostback() As Boolean
'Returns true if we are currently in an async postback to a page
'Get current ScriptManager, if there is one
Dim sm As ScriptManager = GetCurrentScriptManager()
'Return false if no ScriptManager
If sm Is Nothing Then Return False
'Otherwise, use value from ScriptManager
Return sm.IsInAsyncPostBack
End Function
Just call IsInAsyncPostback() from within Application_Error to get a boolean indicating the current state.
You're getting generic ASP.NET errors at the client because attempting to transfer / redirect an async request will generate more errors, replacing and thereby obfuscating the original error. You can use the code above to prevent transferring or redirecting in such cases.
Also note another discovery I made: Even though you can access the ScriptManager object using this method, for some reason setting its AsyncPostBackErrorMessage property from within Application_Error does not work. The new value is not passed to the client. Therefore, you will still need to handle the ScriptManager's OnAsyncPostBackError event in the page class.