/mcs/class/referencesource/System.Web/HttpException.cs
C# | 700 lines | 402 code | 161 blank | 137 comment | 50 complexity | 1e3b70666bc30d6deb7ea36355c06b39 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
- //------------------------------------------------------------------------------
- // <copyright file="HttpException.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- //------------------------------------------------------------------------------
- /*
- * Exception thrown by ASP.NET managed runtime
- *
- * Copyright (c) 1998 Microsoft Corporation
- */
- namespace System.Web {
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Collections;
- using System.Collections.Specialized;
- using System.Configuration;
- using System.Diagnostics.CodeAnalysis;
- using System.Security;
- using System.Globalization;
- using System.CodeDom.Compiler;
- using System.Security.Permissions;
- using System.Web.Hosting;
- using System.Web.Management;
- using System.Web.Util;
- /// <devdoc>
- /// <para> Enables ASP.NET
- /// to send exception information.</para>
- /// </devdoc>
- [Serializable]
- public class HttpException : ExternalException {
- private const int FACILITY_WIN32 = 7;
- private int _httpCode;
- private ErrorFormatter _errorFormatter;
- private int _webEventCode = WebEventCodes.UndefinedEventCode;
- // N.B. The last error code can be lost if we were to
- // call UnsafeNativeMethods.GetLastError from this function
- // and it were not yet jitted.
- internal static int HResultFromLastError(int lastError) {
- int hr;
- if (lastError < 0) {
- hr = lastError;
- }
- else {
- hr = (int)(((uint)lastError & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);
- }
- return hr;
- }
- /// <devdoc>
- /// <para>Creates a new Exception based on the previous Exception. </para>
- /// </devdoc>
- public static HttpException CreateFromLastError(String message) {
- return new HttpException(message, HResultFromLastError(Marshal.GetLastWin32Error()));
- }
- /// <devdoc>
- /// <para> Default constructor.</para>
- /// </devdoc>
- public HttpException() {}
- /// <devdoc>
- /// <para>
- /// Construct an exception using error message.
- /// </para>
- /// </devdoc>
- public HttpException(String message)
- : base(message) {
- }
- internal HttpException(String message, Exception innerException, int code)
-
- : base(message, innerException) {
- _webEventCode = code;
- }
-
- /// <devdoc>
- /// <para>Construct an exception using error message and hr.</para>
- /// </devdoc>
- public HttpException(String message, int hr)
- : base(message) {
- HResult = hr;
- }
- /// <devdoc>
- /// <para>Construct an exception using error message, HTTP code,
- /// and innerException
- /// .</para>
- /// </devdoc>
- public HttpException(String message, Exception innerException)
- : base(message, innerException) {
- }
- /// <devdoc>
- /// <para>Construct an exception using HTTP error code, error message,
- /// and innerException
- /// .</para>
- /// </devdoc>
- public HttpException(int httpCode, String message, Exception innerException)
- : base(message, innerException) {
- _httpCode = httpCode;
- }
- /// <devdoc>
- /// <para>Construct an
- /// exception using HTTP error code and error message.</para>
- /// </devdoc>
- public HttpException(int httpCode, String message)
- : base(message) {
- _httpCode = httpCode;
- }
- /// <devdoc>
- /// <para> Construct an exception
- /// using HTTP error code, error message, and hr.</para>
- /// </devdoc>
- public HttpException(int httpCode, String message, int hr)
- : base(message) {
- HResult = hr;
- _httpCode = httpCode;
- }
- /// <devdoc>
- /// <para> Contructor used for derialization.</para>
- /// </devdoc>
- protected HttpException(SerializationInfo info, StreamingContext context)
- :base(info, context) {
- _httpCode = info.GetInt32("_httpCode");
- }
- /// <devdoc>
- /// <para>Serialize the object.</para>
- /// </devdoc>
- //[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
- [SuppressMessage("Microsoft.Security", "CA2110:SecureGetObjectDataOverrides", Justification = "Base class has demand")]
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("_httpCode", _httpCode);
- }
- /*
- * If we have an Http code (non-zero), return it. Otherwise, return
- * the inner exception's code. If there isn't one, return 500.
- */
- /// <devdoc>
- /// <para>HTTP return code to send back to client. If there is a
- /// non-zero Http code, it is returned. Otherwise, the System.HttpException.innerException
- /// code is returned. If
- /// there isn't an inner exception, error code 500 is returned.</para>
- /// </devdoc>
- public int GetHttpCode() {
- return GetHttpCodeForException(this);
- }
- internal void SetFormatter(ErrorFormatter errorFormatter) {
- _errorFormatter = errorFormatter;
- }
- internal static int GetHttpCodeForException(Exception e) {
- if (e is HttpException) {
- HttpException he = (HttpException)e;
- // If the HttpException specifies an HTTP code, use it
- if (he._httpCode > 0)
- return he._httpCode;
- }
- /*
- 404 conversion is done in HttpAplpication.MapHttpHandler
- else if (e is FileNotFoundException || e is DirectoryNotFoundException)
- {
- code = 404;
- }
- */
- else if (e is UnauthorizedAccessException) {
- return 401;
- }
- else if (e is PathTooLongException) {
- return 414;
- }
- // If there is an inner exception, try to get the code from it
- if (e.InnerException != null)
- return GetHttpCodeForException(e.InnerException);
- // If all else fails, use 500
- return 500;
- }
- /*
- * Return the formatter associated with this exception
- */
- internal static ErrorFormatter GetErrorFormatter(Exception e) {
- Exception inner = e.InnerException;
- ErrorFormatter nestedFormatter = null;
- // First, see if the inner exception has a formatter
- if (inner != null) {
- nestedFormatter = GetErrorFormatter(inner);
- if (nestedFormatter != null)
- return nestedFormatter;
- if (inner is ConfigurationException)
- {
- ConfigurationException ce = inner as ConfigurationException;
- if (ce != null && ce.Filename != null)
- nestedFormatter = new ConfigErrorFormatter((ConfigurationException)inner);
- }
- else if (inner is SecurityException)
- nestedFormatter = new SecurityErrorFormatter(inner);
- }
- // If it does, return it rather than our own
- if (nestedFormatter != null)
- return nestedFormatter;
- HttpException httpExc = e as HttpException;
- if (httpExc != null)
- return httpExc._errorFormatter;
- return null;
- }
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public string GetHtmlErrorMessage() {
- ErrorFormatter formatter = GetErrorFormatter(this);
- if (formatter == null) return null;
- return formatter.GetHtmlErrorMessage();
- }
- public int WebEventCode {
- get { return _webEventCode; }
- internal set { _webEventCode = value; }
- }
- }
- /// <devdoc>
- /// <para> Exception thrown when a generic error occurs.</para>
- /// </devdoc>
- [Serializable]
- public sealed class HttpUnhandledException : HttpException {
- public HttpUnhandledException() {}
- public HttpUnhandledException(String message)
- : base(message) {
- }
- public HttpUnhandledException(string message, Exception innerException)
- : base(message, innerException) {
-
- SetFormatter(new UnhandledErrorFormatter(innerException, message, null));
- }
- /// <internalonly/>
- internal HttpUnhandledException(string message, string postMessage, Exception innerException)
- : base(message, innerException) {
-
- SetFormatter(new UnhandledErrorFormatter(innerException, message, postMessage));
- }
- private HttpUnhandledException(SerializationInfo info, StreamingContext context)
- :base(info, context) {
- }
- }
- /// <devdoc>
- /// <para> Exception thrown when a compilation error occurs.</para>
- /// </devdoc>
- [Serializable]
- public sealed class HttpCompileException : HttpException {
- private CompilerResults _results;
- private string _sourceCode;
- public HttpCompileException() {
- }
- public HttpCompileException(string message) : base(message) {
- }
- public HttpCompileException(String message, Exception innerException) : base(message, innerException) {
- }
- public HttpCompileException(CompilerResults results, string sourceCode) {
- _results = results;
- _sourceCode = sourceCode;
- SetFormatter(new DynamicCompileErrorFormatter(this));
- }
- private HttpCompileException(SerializationInfo info, StreamingContext context)
- :base(info, context) {
- _results = (CompilerResults) info.GetValue("_results", typeof(CompilerResults));
- _sourceCode = info.GetString("_sourceCode");
- }
- // Determines whether the compile exception should be cached
- private bool _dontCache;
- internal bool DontCache {
- get { return _dontCache; }
- set { _dontCache = value; }
- }
- // The virtualpath depdencies for current buildresult.
- private ICollection _virtualPathDependencies;
- internal ICollection VirtualPathDependencies {
- get { return _virtualPathDependencies; }
- set { _virtualPathDependencies = value; }
- }
- /// <devdoc>
- /// <para>Serialize the object.</para>
- /// </devdoc>
- [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("_results", _results);
- info.AddValue("_sourceCode", _sourceCode);
- }
- private const string compileErrorFormat = "{0}({1}): error {2}: {3}";
- /// <devdoc>
- /// <para> The first compilation error.</para>
- /// </devdoc>
- public override string Message {
- get {
- // Return the first compile error as the exception message
- CompilerError e = FirstCompileError;
- if (e == null)
- return base.Message;
- string message = String.Format(CultureInfo.CurrentCulture, compileErrorFormat,
- e.FileName, e.Line, e.ErrorNumber, e.ErrorText);
-
- return message;
- }
- }
- /// <devdoc>
- /// <para> The CompilerResults object describing the compile error.</para>
- /// </devdoc>
- public CompilerResults Results {
- [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
- get {
- return _results;
- }
- }
- internal CompilerResults ResultsWithoutDemand {
- get {
- return _results;
- }
- }
- /// <devdoc>
- /// <para> The source code that was compiled.</para>
- /// </devdoc>
- public string SourceCode {
- [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
- get {
- return _sourceCode;
- }
- }
- internal string SourceCodeWithoutDemand {
- get {
- return _sourceCode;
- }
- }
- // Return the first compile error, or null if there isn't one
- internal CompilerError FirstCompileError {
- get {
- if (_results == null || !_results.Errors.HasErrors)
- return null;
- CompilerError e = null;
- foreach (CompilerError error in _results.Errors) {
-
- // Ignore warnings
- if (error.IsWarning) continue;
- // If we found an error that's not in the generated code, use it
- if (HttpRuntime.CodegenDirInternal != null && error.FileName != null &&
- !StringUtil.StringStartsWith(error.FileName, HttpRuntime.CodegenDirInternal)) {
- e = error;
- break;
- }
- // The current error is in the generated code. Keep track of
- // it if it's the first one, but keep on looking in case we find another
- // one that's not in the generated code (ASURT 62600)
- if (e == null)
- e = error;
- }
- return e;
- }
- }
- }
- /// <devdoc>
- /// <para> Exception thrown when a parse error occurs.</para>
- /// </devdoc>
- [Serializable]
- public sealed class HttpParseException : HttpException {
- private VirtualPath _virtualPath;
- private int _line;
- private ParserErrorCollection _parserErrors;
- public HttpParseException() {
- }
- public HttpParseException(string message) : base(message) {
- }
- public HttpParseException(String message, Exception innerException) : base(message, innerException) {
- }
- public HttpParseException(string message, Exception innerException, string virtualPath,
- string sourceCode, int line) : this(message, innerException,
- System.Web.VirtualPath.CreateAllowNull(virtualPath), sourceCode, line) {}
- internal HttpParseException(string message, Exception innerException, VirtualPath virtualPath,
- string sourceCode, int line)
- : base(message, innerException) {
- _virtualPath = virtualPath;
- _line = line;
- string formatterMessage;
- if (innerException != null)
- formatterMessage = innerException.Message;
- else
- formatterMessage = message;
- SetFormatter(new ParseErrorFormatter(this, System.Web.VirtualPath.GetVirtualPathString(virtualPath), sourceCode,
- line, formatterMessage));
- }
- private HttpParseException(SerializationInfo info, StreamingContext context)
- :base(info, context) {
- _virtualPath = (VirtualPath)info.GetValue("_virtualPath", typeof(VirtualPath));
- _line = info.GetInt32("_line");
- _parserErrors = (ParserErrorCollection)info.GetValue("_parserErrors", typeof(ParserErrorCollection));
- }
- /// <devdoc>
- /// <para>Serialize the object.</para>
- /// </devdoc>
- [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("_virtualPath", _virtualPath);
- info.AddValue("_line", _line);
- info.AddValue("_parserErrors", _parserErrors);
- }
- /// <devdoc>
- /// <para> The physical path to source file that has the error.</para>
- /// </devdoc>
- public string FileName {
- get {
- string physicalPath = _virtualPath.MapPathInternal();
- if (physicalPath == null)
- return null;
- // Demand path discovery before returning the path (ASURT 123798)
- InternalSecurityPermissions.PathDiscovery(physicalPath).Demand();
- return physicalPath;
- }
- }
- /// <devdoc>
- /// <para> The virtual path to source file that has the error.</para>
- /// </devdoc>
- public string VirtualPath {
- get {
- return System.Web.VirtualPath.GetVirtualPathString(_virtualPath);
- }
- }
- internal VirtualPath VirtualPathObject {
- get {
- return _virtualPath;
- }
- }
- /// <devdoc>
- /// <para> The CompilerResults object describing the compile error.</para>
- /// </devdoc>
- public int Line {
- get { return _line;}
- }
- // The set of parser errors
- public ParserErrorCollection ParserErrors {
- get {
- if (_parserErrors == null) {
- _parserErrors = new ParserErrorCollection();
- ParserError thisError = new ParserError(Message, _virtualPath, _line);
- _parserErrors.Add(thisError);
- }
- return _parserErrors;
- }
- }
- }
- /// <devdoc>
- /// <para> Exception thrown when a potentially unsafe input string is detected (ASURT 122278)</para>
- /// </devdoc>
- [Serializable]
- public sealed class HttpRequestValidationException : HttpException {
- public HttpRequestValidationException() {
- }
- public HttpRequestValidationException(string message) : base(message) {
- SetFormatter(new UnhandledErrorFormatter(
- this, SR.GetString(SR.Dangerous_input_detected_descr), null));
- }
- public HttpRequestValidationException(String message, Exception innerException) : base(message, innerException) {
- }
- private HttpRequestValidationException(SerializationInfo info, StreamingContext context)
- :base(info, context) {
- }
- }
- [Serializable]
- public sealed class ParserError {
- private int _line;
- private VirtualPath _virtualPath;
- private string _errorText;
- private Exception _exception;
- public ParserError() {
- }
- public ParserError(string errorText, string virtualPath, int line)
- : this(errorText, System.Web.VirtualPath.CreateAllowNull(virtualPath), line) {
- }
- internal ParserError(string errorText, VirtualPath virtualPath, int line) {
- _virtualPath = virtualPath;
- _line = line;
- _errorText = errorText;
- }
- // The original exception that introduces the Parser Error
- internal Exception Exception {
- get { return _exception; }
- set { _exception = value; }
- }
- // The virtualPath where the parser error occurs.
- public string VirtualPath {
- get { return System.Web.VirtualPath.GetVirtualPathString(_virtualPath); }
- set { _virtualPath = System.Web.VirtualPath.Create(value); }
- }
- // The description error text of the error.
- public string ErrorText {
- get { return _errorText; }
- set { _errorText = value; }
- }
- // The line where the parser error occurs.
- public int Line {
- get { return _line; }
- set { _line = value; }
- }
- }
- [Serializable]
- public sealed class ParserErrorCollection : CollectionBase {
- public ParserErrorCollection() {
- }
- public ParserErrorCollection(ParserError[] value) {
- this.AddRange(value);
- }
- public ParserError this[int index] {
- get { return ((ParserError)List[index]); }
- set { List[index] = value; }
- }
- public int Add(ParserError value) {
- return List.Add(value);
- }
- public void AddRange(ParserError[] value) {
- if (value == null) {
- throw new ArgumentNullException("value");
- }
- for (int i = 0; i < value.Length; i++) {
- this.Add(value[i]);
- }
- }
- public void AddRange(ParserErrorCollection value) {
- if (value == null) {
- throw new ArgumentNullException("value");
- }
- foreach(ParserError parserError in value) {
- this.Add(parserError);
- }
- }
- public bool Contains(ParserError value) {
- return List.Contains(value);
- }
- public void CopyTo(ParserError[] array, int index) {
- List.CopyTo(array, index);
- }
- public int IndexOf(ParserError value) {
- return List.IndexOf(value);
- }
- public void Insert(int index, ParserError value) {
- List.Insert(index, value);
- }
- public void Remove(ParserError value) {
- List.Remove(value);
- }
- }
- }