问题
If I add the following line to an ASP.NET MVC action method
throw new Exception("outer", new SecurityException("inner"));
the error that is actually displayed on the yellow screen of death is the inner SecurityException with absolutely no mention of the outer exception.
SecurityException
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
Exception Details: System.Security.SecurityException: inner
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[SecurityException: inner]
Is this expected behavior?
It doesn't seem to matter what type the outer exception is. Even if it is another SecurityException, the message is never displayed. The default SecurityException error message is so vague that I want to catch it and add some more specific information. This works fine if I do not include the original SecurityException as the innerException but ideally I would like to do this.
回答1:
This behaviour originates in the ASP.NET "core", not in ASP.NET MVC. Unfortunately, the error formatter classes are internal, and the consuming types do not provide any extension points that would allow one to tweak the behaviour without replacing the error reporting mechanism. The workaround is to replace the default "yellow screen of death" page by a custom error page/view in which one exposes the information that one prefers.
This is exactly what one should usually be doing for production. In your case, it just means that you would have an alternate version for debug instead of using the ASP.NET-provided default.
回答2:
in general you should never throw Exception class/object directly but only derived ones, for example:
throw new SecurityException("user should not be allowed to access this method...");
in a situation like this what are you missing in the log or in the page?
if you use an application global exception handler and you log from there with either Log4Net
or NLog
you should be able to access all exception chain from outer to inner and so on depending on how you configure and use the logging framework. The Yellow page of IIS / ASP.NET might not be complete but should show the stack trace anyway.
if you want to throw your own exception from a catch block you wrap the actual exception coming from the catch in this way:
throw new SecurityException("user should not be allowed...", exc);
Edit: tried what you suggested and got the following logged in a text file by Log4Net:
System.Security.SecurityException: more explicit exception ---> System.Security.SecurityException: original exception at EDICheckerApp.Program.boom() in C:\DEV_RPP\Program.cs:line 45
--- End of inner exception stack trace --- at EDICheckerApp.Program.boom() in C:\DEV_RPP\Program.cs:line 49
at EDICheckerApp.Program.Main(String[] args) in C:\DEV_RPP\Program.cs:line 27
来源:https://stackoverflow.com/questions/9310320/throwing-exception-with-inner-securityexception-only-displays-inner-exception-in