1 // 2 // System.Web.HttpException 3 // 4 // Authors: 5 // Patrik Torstensson (Patrik.Torstensson@labs2.com) 6 // Gonzalo Paniagua Javier (gonzalo@ximian.com) 7 // 8 // (c) 2002 Patrik Torstensson 9 // (c) 2003 Ximian, Inc. (http://www.ximian.com) 10 // Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com) 11 // 12 // Permission is hereby granted, free of charge, to any person obtaining 13 // a copy of this software and associated documentation files (the 14 // "Software"), to deal in the Software without restriction, including 15 // without limitation the rights to use, copy, modify, merge, publish, 16 // distribute, sublicense, and/or sell copies of the Software, and to 17 // permit persons to whom the Software is furnished to do so, subject to 18 // the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be 21 // included in all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 // 31 32 using System.IO; 33 using System.Runtime.Serialization; 34 using System.Runtime.InteropServices; 35 using System.Security.Permissions; 36 using System.Text; 37 using System.Web.Util; 38 using System.Web.Compilation; 39 using System.Web.Management; 40 using System.Collections.Specialized; 41 42 namespace System.Web 43 { 44 // CAS 45 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] 46 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] 47 [Serializable] 48 public class HttpException : ExternalException 49 { 50 const string DEFAULT_DESCRIPTION_TEXT = "Error processing request."; 51 const string ERROR_404_DESCRIPTION = "The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly."; 52 53 int webEventCode = WebEventCodes.UndefinedEventCode; 54 int http_code = 500; 55 string resource_name; 56 string description; 57 ExceptionPageTemplate pageTemplate; 58 59 ExceptionPageTemplate PageTemplate { 60 get { 61 if (pageTemplate == null) 62 pageTemplate = GetPageTemplate (); 63 return pageTemplate; 64 } 65 } 66 public 67 int WebEventCode 68 { 69 get { return webEventCode; } 70 } 71 HttpException()72 public HttpException () 73 { 74 } 75 HttpException(string message)76 public HttpException (string message) 77 : base (message) 78 { 79 } 80 HttpException(string message, Exception innerException)81 public HttpException (string message, Exception innerException) 82 : base (message, innerException) 83 { 84 } 85 HttpException(int httpCode, string message)86 public HttpException (int httpCode, string message) : base (message) 87 { 88 http_code = httpCode; 89 } 90 HttpException(int httpCode, string message, string resourceName)91 internal HttpException (int httpCode, string message, string resourceName) : this (httpCode, message) 92 { 93 resource_name = resourceName; 94 } 95 HttpException(int httpCode, string message, string resourceName, string description)96 internal HttpException (int httpCode, string message, string resourceName, string description) : this (httpCode, message, resourceName) 97 { 98 this.description = description; 99 } 100 HttpException(SerializationInfo info, StreamingContext context)101 protected HttpException (SerializationInfo info, StreamingContext context) 102 : base (info, context) 103 { 104 http_code = info.GetInt32 ("_httpCode"); 105 webEventCode = info.GetInt32 ("_webEventCode"); 106 } 107 108 [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)] GetObjectData(SerializationInfo info, StreamingContext context)109 public override void GetObjectData (SerializationInfo info, StreamingContext context) 110 { 111 base.GetObjectData (info, context); 112 info.AddValue ("_httpCode", http_code); 113 info.AddValue ("_webEventCode", webEventCode); 114 } 115 HttpException(int httpCode, string message, int hr)116 public HttpException (int httpCode, string message, int hr) 117 : base (message, hr) 118 { 119 http_code = httpCode; 120 } 121 HttpException(string message, int hr)122 public HttpException (string message, int hr) 123 : base (message, hr) 124 { 125 } 126 HttpException(int httpCode, string message, Exception innerException)127 public HttpException (int httpCode, string message, Exception innerException) 128 : base (message, innerException) 129 { 130 http_code = httpCode; 131 } 132 HttpException(int httpCode, string message, Exception innerException, string resourceName)133 internal HttpException (int httpCode, string message, Exception innerException, string resourceName) 134 : this (httpCode, message, innerException) 135 { 136 resource_name = resourceName; 137 } 138 139 [MonoTODO ("For now just the default template is created. Means of user-provided templates are to be implemented yet.")] GetPageTemplate()140 ExceptionPageTemplate GetPageTemplate () 141 { 142 ExceptionPageTemplate template = new DefaultExceptionPageTemplate (); 143 template.Init (); 144 145 return template; 146 } 147 GetHtmlErrorMessage()148 public string GetHtmlErrorMessage () 149 { 150 var values = new ExceptionPageTemplateValues (); 151 ExceptionPageTemplate template = PageTemplate; 152 153 try { 154 values.Add (ExceptionPageTemplate.Template_RuntimeVersionInformationName, RuntimeHelpers.MonoVersion); 155 values.Add (ExceptionPageTemplate.Template_AspNetVersionInformationName, Environment.Version.ToString ()); 156 157 HttpContext ctx = HttpContext.Current; 158 ExceptionPageTemplateType pageType = ExceptionPageTemplateType.Standard; 159 160 if (ctx != null && ctx.IsCustomErrorEnabled) { 161 if (http_code != 404 && http_code != 403) { 162 FillDefaultCustomErrorValues (values); 163 pageType = ExceptionPageTemplateType.CustomErrorDefault; 164 } else 165 FillDefaultErrorValues (false, false, null, values); 166 } else { 167 Exception ex = GetBaseException (); 168 if (ex == null) 169 ex = this; 170 171 values.Add (ExceptionPageTemplate.Template_FullStackTraceName, FormatFullStackTrace ()); 172 HtmlizedException htmlException = ex as HtmlizedException; 173 if (htmlException == null) 174 FillDefaultErrorValues (true, true, ex, values); 175 else { 176 pageType = ExceptionPageTemplateType.Htmlized; 177 FillHtmlizedErrorValues (values, htmlException, ref pageType); 178 } 179 } 180 181 return template.Render (values, pageType); 182 } catch (Exception ex) { 183 Console.Error.WriteLine ("An exception has occurred while generating HttpException page:"); 184 Console.Error.WriteLine (ex); 185 Console.Error.WriteLine (); 186 Console.Error.WriteLine ("The actual exception which was being reported was:"); 187 Console.Error.WriteLine (this); 188 189 // we need the try/catch block in case the 190 // problem was with MapPath, which will cause 191 // IsCustomErrorEnabled to throw an exception 192 try { 193 FillDefaultCustomErrorValues (values); 194 return template.Render (values, ExceptionPageTemplateType.CustomErrorDefault); 195 } catch { 196 return DoubleFaultExceptionMessage; 197 } 198 } 199 } 200 201 internal virtual string Description { 202 get { 203 if (description != null) 204 return description; 205 206 return DEFAULT_DESCRIPTION_TEXT; 207 } 208 209 set { 210 if (value != null && value.Length > 0) 211 description = value; 212 else 213 description = DEFAULT_DESCRIPTION_TEXT; 214 } 215 } 216 NewWithCode(string message, int webEventCode)217 internal static HttpException NewWithCode (string message, int webEventCode) 218 { 219 var ret = new HttpException (message); 220 ret.SetWebEventCode (webEventCode); 221 222 return ret; 223 } 224 NewWithCode(string message, Exception innerException, int webEventCode)225 internal static HttpException NewWithCode (string message, Exception innerException, int webEventCode) 226 { 227 var ret = new HttpException (message, innerException); 228 ret.SetWebEventCode (webEventCode); 229 230 return ret; 231 } 232 NewWithCode(int httpCode, string message, int webEventCode)233 internal static HttpException NewWithCode (int httpCode, string message, int webEventCode) 234 { 235 var ret = new HttpException (httpCode, message); 236 ret.SetWebEventCode (webEventCode); 237 238 return ret; 239 } 240 NewWithCode(int httpCode, string message, Exception innerException, string resourceName, int webEventCode)241 internal static HttpException NewWithCode (int httpCode, string message, Exception innerException, string resourceName, int webEventCode) 242 { 243 var ret = new HttpException (httpCode, message, innerException, resourceName); 244 ret.SetWebEventCode (webEventCode); 245 246 return ret; 247 } 248 NewWithCode(int httpCode, string message, string resourceName, int webEventCode)249 internal static HttpException NewWithCode (int httpCode, string message, string resourceName, int webEventCode) 250 { 251 var ret = new HttpException (httpCode, message, resourceName); 252 ret.SetWebEventCode (webEventCode); 253 254 return ret; 255 } 256 NewWithCode(int httpCode, string message, Exception innerException, int webEventCode)257 internal static HttpException NewWithCode (int httpCode, string message, Exception innerException, int webEventCode) 258 { 259 var ret = new HttpException (httpCode, message, innerException); 260 ret.SetWebEventCode (webEventCode); 261 262 return ret; 263 } 264 SetWebEventCode(int webEventCode)265 internal void SetWebEventCode (int webEventCode) 266 { 267 this.webEventCode = webEventCode; 268 } 269 FormatFullStackTrace()270 string FormatFullStackTrace () 271 { 272 Exception ex = this; 273 var builder = new StringBuilder ("\r\n<!--"); 274 string trace; 275 string message; 276 bool haveTrace, first = true; 277 278 while (ex != null) { 279 trace = ex.StackTrace; 280 message = ex.Message; 281 haveTrace = !String.IsNullOrEmpty (trace); 282 283 if (!haveTrace && String.IsNullOrEmpty (message)) { 284 ex = ex.InnerException; 285 continue; 286 } 287 288 if (first) 289 first = false; 290 else 291 builder.Append ("\r\n"); 292 293 builder.Append ("\r\n[" + ex.GetType () + "]: " + HtmlEncode (message) + "\r\n"); 294 if (haveTrace) 295 builder.Append (ex.StackTrace); 296 297 ex = ex.InnerException; 298 } 299 builder.Append ("\r\n-->\r\n"); 300 301 return builder.ToString (); 302 } 303 FillHtmlizedErrorValues(ExceptionPageTemplateValues values, HtmlizedException exc, ref ExceptionPageTemplateType pageType)304 void FillHtmlizedErrorValues (ExceptionPageTemplateValues values, HtmlizedException exc, ref ExceptionPageTemplateType pageType) 305 { 306 bool isParseException = exc is ParseException; 307 bool isCompileException = (!isParseException && exc is CompilationException); 308 values.Add (ExceptionPageTemplate.Template_PageTitleName, HtmlEncode (exc.Title)); 309 values.Add (ExceptionPageTemplate.Template_DescriptionName, HtmlEncode (exc.Description)); 310 values.Add (ExceptionPageTemplate.Template_StackTraceName, HtmlEncode (exc.StackTrace)); 311 values.Add (ExceptionPageTemplate.Template_ExceptionTypeName, exc.GetType ().ToString ()); 312 values.Add (ExceptionPageTemplate.Template_ExceptionMessageName, HtmlEncode (exc.Message)); 313 values.Add (ExceptionPageTemplate.Template_DetailsName, HtmlEncode (exc.ErrorMessage)); 314 315 string origin; 316 if (isParseException) 317 origin = "Parser"; 318 else if (isCompileException) 319 origin = "Compiler"; 320 else 321 origin = "Other"; 322 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionOriginName, origin); 323 if (exc.FileText != null) { 324 pageType |= ExceptionPageTemplateType.SourceError; 325 StringBuilder shortSource = new StringBuilder (); 326 StringBuilder longSource; 327 328 if (isCompileException) 329 longSource = new StringBuilder (); 330 else 331 longSource = null; 332 FormatSource (shortSource, longSource, exc); 333 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionShortSourceName, shortSource.ToString ()); 334 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionLongSourceName, longSource != null ? longSource.ToString () : null); 335 336 if (exc.SourceFile != exc.FileName) 337 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionSourceFileName, FormatSourceFile (exc.SourceFile)); 338 else 339 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionSourceFileName, FormatSourceFile (exc.FileName)); 340 if (isParseException || isCompileException) { 341 int[] errorLines = exc.ErrorLines; 342 int numErrors = errorLines != null ? errorLines.Length : 0; 343 var lines = new StringBuilder (); 344 for (int i = 0; i < numErrors; i++) { 345 if (i > 0) 346 lines.Append (", "); 347 lines.Append (errorLines [i]); 348 } 349 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionErrorLinesName, lines.ToString ()); 350 } 351 } else 352 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionSourceFileName, FormatSourceFile (exc.FileName)); 353 354 if (isCompileException) { 355 CompilationException cex = exc as CompilationException; 356 StringCollection output = cex.CompilerOutput; 357 358 if (output != null && output.Count > 0) { 359 pageType |= ExceptionPageTemplateType.CompilerOutput; 360 var sb = new StringBuilder (); 361 bool first = true; 362 foreach (string s in output) { 363 sb.Append (HtmlEncode (s)); 364 if (first) { 365 sb.Append ("<br/>"); 366 first = false; 367 } 368 sb.Append ("<br/>"); 369 } 370 371 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionCompilerOutputName, sb.ToString ()); 372 } 373 } 374 } 375 FillDefaultCustomErrorValues(ExceptionPageTemplateValues values)376 void FillDefaultCustomErrorValues (ExceptionPageTemplateValues values) 377 { 378 values.Add (ExceptionPageTemplate.Template_PageTitleName, "Runtime Error"); 379 values.Add (ExceptionPageTemplate.Template_ExceptionTypeName, "Runtime Error"); 380 values.Add (ExceptionPageTemplate.Template_ExceptionMessageName, "A runtime error has occurred"); 381 values.Add (ExceptionPageTemplate.Template_DescriptionName, "An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed (for security reasons)."); 382 values.Add (ExceptionPageTemplate.Template_DetailsName, "To enable the details of this specific error message to be viewable, please create a <customErrors> tag within a "web.config" configuration file located in the root directory of the current web application. This <customErrors> tag should then have its "mode" attribute set to "Off"."); 383 } 384 FillDefaultErrorValues(bool showTrace, bool showExceptionType, Exception baseEx, ExceptionPageTemplateValues values)385 void FillDefaultErrorValues (bool showTrace, bool showExceptionType, Exception baseEx, ExceptionPageTemplateValues values) 386 { 387 if (baseEx == null) 388 baseEx = this; 389 390 values.Add (ExceptionPageTemplate.Template_PageTitleName, String.Format ("Error{0}", http_code != 0 ? " " + http_code : String.Empty)); 391 values.Add (ExceptionPageTemplate.Template_ExceptionTypeName, showExceptionType ? baseEx.GetType ().ToString () : "Runtime error"); 392 values.Add (ExceptionPageTemplate.Template_ExceptionMessageName, http_code == 404 ? "The resource cannot be found." : HtmlEncode (baseEx.Message)); 393 394 string tmp = http_code != 0 ? "HTTP " + http_code + "." : String.Empty; 395 values.Add (ExceptionPageTemplate.Template_DescriptionName, tmp + (http_code == 404 ? ERROR_404_DESCRIPTION : HtmlEncode (Description))); 396 397 if (!String.IsNullOrEmpty (resource_name)) 398 values.Add (ExceptionPageTemplate.Template_DetailsName, "Requested URL: " + HtmlEncode (resource_name)); 399 else if (http_code == 404) 400 values.Add (ExceptionPageTemplate.Template_DetailsName, "No virtual path information available."); 401 else if (baseEx is HttpException) { 402 tmp = ((HttpException)baseEx).Description; 403 values.Add (ExceptionPageTemplate.Template_DetailsName, !String.IsNullOrEmpty (tmp) ? HtmlEncode (tmp) : "Web exception occurred but no additional error description given."); 404 } else { 405 var sb = new StringBuilder ("Non-web exception."); 406 407 tmp = baseEx.Source; 408 if (!String.IsNullOrEmpty (tmp)) 409 sb.AppendFormat (" Exception origin (name of application or object): {0}.", HtmlEncode (tmp)); 410 tmp = baseEx.HelpLink; 411 if (!String.IsNullOrEmpty (tmp)) 412 sb.AppendFormat (" Additional information is available at {0}", HtmlEncode (tmp)); 413 414 values.Add (ExceptionPageTemplate.Template_DetailsName, sb.ToString ()); 415 } 416 417 if (showTrace) { 418 string stackTrace = baseEx.StackTrace; 419 if (!String.IsNullOrEmpty (stackTrace)) 420 values.Add (ExceptionPageTemplate.Template_StackTraceName, HtmlEncode (stackTrace)); 421 } 422 } 423 HtmlEncode(string s)424 static string HtmlEncode (string s) 425 { 426 if (String.IsNullOrEmpty (s)) 427 return s; 428 429 string res = HttpUtility.HtmlEncode (s); 430 return res.Replace ("\r\n", "<br />"); 431 } 432 FormatSourceFile(string filename)433 string FormatSourceFile (string filename) 434 { 435 if (filename == null || filename.Length == 0) 436 return String.Empty; 437 438 if (filename.StartsWith ("@@")) 439 return "[internal] <!-- " + HttpUtility.HtmlEncode (filename) + " -->"; 440 441 return HttpUtility.HtmlEncode (filename); 442 } 443 FormatSource(StringBuilder builder, StringBuilder longVersion, HtmlizedException e)444 static void FormatSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e) 445 { 446 if (e is CompilationException) 447 WriteCompilationSource (builder, longVersion, e); 448 else 449 WritePageSource (builder, e); 450 } 451 WriteCompilationSource(StringBuilder builder, StringBuilder longVersion, HtmlizedException e)452 static void WriteCompilationSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e) 453 { 454 int [] a = e.ErrorLines; 455 string s; 456 int line = 0; 457 int index = 0; 458 int errline = 0; 459 460 if (a != null && a.Length > 0) 461 errline = a [0]; 462 463 int begin = errline - 2; 464 int end = errline + 2; 465 466 if (begin < 0) 467 begin = 0; 468 469 string tmp; 470 using (TextReader reader = new StringReader (e.FileText)) { 471 while ((s = reader.ReadLine ()) != null) { 472 line++; 473 if (line < begin || line > end) { 474 if (longVersion != null) 475 longVersion.AppendFormat ("{0}: {1}\r\n", line, HtmlEncode (s)); 476 continue; 477 } 478 479 if (errline == line) { 480 if (longVersion != null) 481 longVersion.Append ("<span class=\"sourceErrorLine\">"); 482 builder.Append ("<span class=\"sourceErrorLine\">"); 483 } 484 485 tmp = String.Format ("{0}: {1}\r\n", line, HtmlEncode (s)); 486 builder.Append (tmp); 487 if (longVersion != null) 488 longVersion.Append (tmp); 489 490 if (line == errline) { 491 builder.Append ("</span>"); 492 if (longVersion != null) 493 longVersion.Append ("</span>"); 494 errline = (++index < a.Length) ? a [index] : 0; 495 } 496 } 497 } 498 } 499 WritePageSource(StringBuilder builder, HtmlizedException e)500 static void WritePageSource (StringBuilder builder, HtmlizedException e) 501 { 502 string s; 503 int line = 0; 504 int beginerror = e.ErrorLines [0]; 505 int enderror = e.ErrorLines [1]; 506 int begin = beginerror - 2; 507 int end = enderror + 2; 508 if (begin <= 0) 509 begin = 1; 510 511 TextReader reader = new StringReader (e.FileText); 512 while ((s = reader.ReadLine ()) != null) { 513 line++; 514 if (line < begin) 515 continue; 516 517 if (line > end) 518 break; 519 520 if (beginerror == line) 521 builder.Append ("<span class=\"sourceErrorLine\">"); 522 523 builder.AppendFormat ("{0}: {1}\r\n", line, HtmlEncode (s)); 524 525 if (enderror <= line) { 526 builder.Append ("</span>"); 527 enderror = end + 1; // one shot 528 } 529 } 530 } 531 GetHttpCode()532 public int GetHttpCode () 533 { 534 return http_code; 535 } 536 CreateFromLastError(string message)537 public static HttpException CreateFromLastError (string message) 538 { 539 WebTrace.WriteLine ("CreateFromLastError"); 540 return new HttpException (message, 0); 541 } 542 543 // Putting this at the end so that the code above isn't bloated 544 const string DoubleFaultExceptionMessage = @"<?xml version=""1.0"" encoding=""utf-8""?> 545 <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""> 546 <html xmlns=""http://www.w3.org/1999/xhtml""> 547 <head> 548 <style type=""text/css""> 549 body { background-color: #FFFFFF; font-size: .75em; font-family: Verdana, Helvetica, Sans-Serif; margin: 0; padding: 0; color: #696969; } 550 a:link { color: #000000; text-decoration: underline; } 551 a:visited { color: #000000; } 552 a:hover { color: #000000; text-decoration: none; } 553 a:active { color: #12eb87; } 554 p, ul { margin-bottom: 20px; line-height: 1.6em; } 555 pre { font-size: 1.2em; margin-left: 20px; margin-top: 0px; } 556 h1, h2, h3, h4, h5, h6 { font-size: 1.6em; color: #000; font-family: Arial, Helvetica, sans-serif; } 557 h1 { font-weight: bold; margin-bottom: 0; margin-top: 0; padding-bottom: 0; } 558 h2 { font-size: 1em; padding: 0 0 0px 0; color: #696969; font-weight: normal; margin-top: 0; margin-bottom: 20px; } 559 h3 { font-size: 1.2em; } 560 h4 { font-size: 1.1em; } 561 h5, h6 { font-size: 1em; } 562 #header { position: relative; margin-bottom: 0px; color: #000; padding: 0; background-color: #5c87b2; height: 38px; padding-left: 10px; } 563 #header h1 { font-weight: bold; padding: 5px 0; margin: 0; color: #fff; border: none; line-height: 2em; font-family: Arial, Helvetica, sans-serif; font-size: 32px !important; } 564 #header-image { float: left; padding: 3px; margin-left: 1px; margin-right: 1px; } 565 #header-text { color: #fff; font-size: 1.4em; line-height: 38px; font-weight: bold; } 566 #main { padding: 20px 20px 15px 20px; background-color: #fff; _height: 1px; } 567 #footer { color: #999; padding: 5px 0; text-align: left; line-height: normal; margin: 20px 0px 0px 0px; font-size: .9em; border-top: solid 1px #5C87B2; } 568 #footer-powered-by { float: right; } 569 .details { font-family: monospace; border: solid 1px #e8eef4; white-space: pre; font-size: 1.2em; overflow: auto; padding: 6px; margin-top: 6px } 570 .details-wrapped { white-space: normal } 571 .details-header { margin-top: 1.5em } 572 .details-header a { font-weight: bold; text-decoration: none } 573 p { margin-bottom: 0.3em; margin-top: 0.1em } 574 .sourceErrorLine { color: #770000; font-weight: bold; } 575 </style> 576 577 <title>Double fault in exception reporting code</title> 578 </head> 579 <body> 580 <h1>Double fault in exception reporting code</h1> 581 <p>While generating HTML with exception report, a double fault has occurred. Please consult your server's console and/or log file to see the actual exception.</p> 582 </body> 583 </html> 584 "; 585 } 586 } 587 588