d4b839f3fdb92fb9815d7077d795e135ef4c4f6b
[mono.git] / mcs / class / System.Web / System.Web / HttpException.cs
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 #if NET_4_0
67                 public
68 #else
69                 internal
70 #endif
71                 int WebEventCode 
72                 {
73                         get { return webEventCode; }
74                 }
75                 
76                 public HttpException ()
77                 {
78                 }
79
80                 public HttpException (string message)
81                         : base (message)
82                 {
83                 }
84
85                 public HttpException (string message, Exception innerException)
86                         : base (message, innerException)
87                 {
88                 }
89
90                 public HttpException (int httpCode, string message) : base (message)
91                 {
92                         http_code = httpCode;
93                 }
94
95                 internal HttpException (int httpCode, string message, string resourceName) : this (httpCode, message)
96                 {
97                         resource_name = resourceName;
98                 }
99
100                 internal HttpException (int httpCode, string message, string resourceName, string description) : this (httpCode, message, resourceName)
101                 {
102                         this.description = description;
103                 }
104                 
105                 protected HttpException (SerializationInfo info, StreamingContext context)
106                         : base (info, context)
107                 {
108                         http_code = info.GetInt32 ("_httpCode");
109                         webEventCode = info.GetInt32 ("_webEventCode");
110                 }
111
112                 [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)]
113                 public override void GetObjectData (SerializationInfo info, StreamingContext context)
114                 {
115                         base.GetObjectData (info, context);
116                         info.AddValue ("_httpCode", http_code);
117                         info.AddValue ("_webEventCode", webEventCode);
118                 }
119
120                 public HttpException (int httpCode, string message, int hr) 
121                         : base (message, hr)
122                 {
123                         http_code = httpCode;
124                 }
125
126                 public HttpException (string message, int hr)
127                         : base (message, hr)
128                 {
129                 }
130         
131                 public HttpException (int httpCode, string message, Exception innerException)
132                         : base (message, innerException)
133                 {
134                         http_code = httpCode;
135                 }
136
137                 internal HttpException (int httpCode, string message, Exception innerException, string resourceName)
138                         : this (httpCode, message, innerException)
139                 {
140                         resource_name = resourceName;
141                 }
142
143                 [MonoTODO ("For now just the default template is created. Means of user-provided templates are to be implemented yet.")]
144                 ExceptionPageTemplate GetPageTemplate ()
145                 {
146                         ExceptionPageTemplate template = new DefaultExceptionPageTemplate ();
147                         template.Init ();
148
149                         return template;
150                 }
151                 
152                 public string GetHtmlErrorMessage ()
153                 {
154                         var values = new ExceptionPageTemplateValues ();
155                         ExceptionPageTemplate template = PageTemplate;
156
157                         try {
158                                 values.Add (ExceptionPageTemplate.Template_RuntimeVersionInformationName, RuntimeHelpers.MonoVersion);
159                                 values.Add (ExceptionPageTemplate.Template_AspNetVersionInformationName, Environment.Version.ToString ());
160                                 
161                                 HttpContext ctx = HttpContext.Current;
162                                 ExceptionPageTemplateType pageType = ExceptionPageTemplateType.Standard;
163
164                                 if (ctx != null && ctx.IsCustomErrorEnabled) {
165                                         if (http_code != 404 && http_code != 403) {
166                                                 FillDefaultCustomErrorValues (values);
167                                                 pageType = ExceptionPageTemplateType.CustomErrorDefault;
168                                         } else
169                                                 FillDefaultErrorValues (false, false, null, values);
170                                 } else {
171                                         Exception ex = GetBaseException ();
172                                         if (ex == null)
173                                                 ex = this;
174
175                                         values.Add (ExceptionPageTemplate.Template_FullStackTraceName, FormatFullStackTrace ());
176                                         HtmlizedException htmlException = ex as HtmlizedException;
177                                         if (htmlException == null)
178                                                 FillDefaultErrorValues (true, true, ex, values);
179                                         else {
180                                                 pageType = ExceptionPageTemplateType.Htmlized;
181                                                 FillHtmlizedErrorValues (values, htmlException, ref pageType);
182                                         }
183                                 }
184                                 
185                                 return template.Render (values, pageType);
186                         } catch (Exception ex) {
187                                 Console.Error.WriteLine ("An exception has occurred while generating HttpException page:");
188                                 Console.Error.WriteLine (ex);
189                                 Console.Error.WriteLine ();
190                                 Console.Error.WriteLine ("The actual exception which was being reported was:");
191                                 Console.Error.WriteLine (this);
192
193                                 // we need the try/catch block in case the
194                                 // problem was with MapPath, which will cause
195                                 // IsCustomErrorEnabled to throw an exception
196                                 try {
197                                         FillDefaultCustomErrorValues (values);
198                                         return template.Render (values, ExceptionPageTemplateType.CustomErrorDefault);
199                                 } catch {
200                                         return DoubleFaultExceptionMessage;
201                                 }
202                         }
203                 }
204
205                 internal virtual string Description {
206                         get {
207                                 if (description != null)
208                                         return description;
209
210                                 return DEFAULT_DESCRIPTION_TEXT;
211                         }
212                         
213                         set {
214                                 if (value != null && value.Length > 0)
215                                         description = value;
216                                 else
217                                         description = DEFAULT_DESCRIPTION_TEXT;
218                         }
219                 }
220
221                 internal static HttpException NewWithCode (string message, int webEventCode)
222                 {
223                         var ret = new HttpException (message);
224                         ret.SetWebEventCode (webEventCode);
225
226                         return ret;
227                 }
228
229                 internal static HttpException NewWithCode (string message, Exception innerException, int webEventCode)
230                 {
231                         var ret = new HttpException (message, innerException);
232                         ret.SetWebEventCode (webEventCode);
233
234                         return ret;
235                 }
236
237                 internal static HttpException NewWithCode (int httpCode, string message, int webEventCode)
238                 {
239                         var ret = new HttpException (httpCode, message);
240                         ret.SetWebEventCode (webEventCode);
241
242                         return ret;
243                 }
244                 
245                 internal static HttpException NewWithCode (int httpCode, string message, Exception innerException, string resourceName, int webEventCode)
246                 {
247                         var ret = new HttpException (httpCode, message, innerException, resourceName);
248                         ret.SetWebEventCode (webEventCode);
249
250                         return ret;
251                 }
252
253                 internal static HttpException NewWithCode (int httpCode, string message, string resourceName, int webEventCode)
254                 {
255                         var ret = new HttpException (httpCode, message, resourceName);
256                         ret.SetWebEventCode (webEventCode);
257
258                         return ret;
259                 }
260
261                 internal static HttpException NewWithCode (int httpCode, string message, Exception innerException, int webEventCode)
262                 {
263                         var ret = new HttpException (httpCode, message, innerException);
264                         ret.SetWebEventCode (webEventCode);
265
266                         return ret;
267                 }
268                 
269                 internal void SetWebEventCode (int webEventCode)
270                 {
271                         this.webEventCode = webEventCode;
272                 }
273                 
274                 string FormatFullStackTrace ()
275                 {
276                         Exception ex = this;
277                         var builder = new StringBuilder ("\r\n<!--");
278                         string trace;
279                         string message;
280                         bool haveTrace, first = true;
281                         
282                         while (ex != null) {
283                                 trace = ex.StackTrace;
284                                 message = ex.Message;
285                                 haveTrace = !String.IsNullOrEmpty (trace);
286                                 
287                                 if (!haveTrace && String.IsNullOrEmpty (message)) {
288                                         ex = ex.InnerException;
289                                         continue;
290                                 }
291
292                                 if (first)
293                                         first = false;
294                                 else
295                                         builder.Append ("\r\n");
296                                 
297                                 builder.Append ("\r\n[" + ex.GetType () + "]: " + HtmlEncode (message) + "\r\n");
298                                 if (haveTrace)
299                                         builder.Append (ex.StackTrace);
300                                 
301                                 ex = ex.InnerException;
302                         }
303                         builder.Append ("\r\n-->\r\n");
304
305                         return builder.ToString ();
306                 }
307
308                 void FillHtmlizedErrorValues (ExceptionPageTemplateValues values, HtmlizedException exc, ref ExceptionPageTemplateType pageType)
309                 {
310                         bool isParseException = exc is ParseException;
311                         bool isCompileException = (!isParseException && exc is CompilationException);
312                         values.Add (ExceptionPageTemplate.Template_PageTitleName, HtmlEncode (exc.Title));
313                         values.Add (ExceptionPageTemplate.Template_DescriptionName, HtmlEncode (exc.Description));
314                         values.Add (ExceptionPageTemplate.Template_StackTraceName, HtmlEncode (exc.StackTrace));
315                         values.Add (ExceptionPageTemplate.Template_ExceptionTypeName, exc.GetType ().ToString ());
316                         values.Add (ExceptionPageTemplate.Template_ExceptionMessageName, HtmlEncode (exc.Message));
317                         values.Add (ExceptionPageTemplate.Template_DetailsName, HtmlEncode (exc.ErrorMessage));
318
319                         string origin;
320                         if (isParseException)
321                                 origin = "Parser";
322                         else if (isCompileException)
323                                 origin = "Compiler";
324                         else
325                                 origin = "Other";
326                         values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionOriginName, origin);
327                         if (exc.FileText != null) {
328                                 pageType |= ExceptionPageTemplateType.SourceError;
329                                 StringBuilder shortSource = new StringBuilder ();
330                                 StringBuilder longSource;
331                                 
332                                 if (isCompileException)
333                                         longSource = new StringBuilder ();
334                                 else
335                                         longSource = null;
336                                 FormatSource (shortSource, longSource, exc);
337                                 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionShortSourceName, shortSource.ToString ());
338                                 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionLongSourceName, longSource != null ? longSource.ToString () : null);
339                                 
340                                 if (exc.SourceFile != exc.FileName)
341                                         values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionSourceFileName, FormatSourceFile (exc.SourceFile));
342                                 else
343                                         values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionSourceFileName, FormatSourceFile (exc.FileName));
344                                 if (isParseException || isCompileException) {
345                                         int[] errorLines = exc.ErrorLines;
346                                         int numErrors = errorLines != null ? errorLines.Length : 0;
347                                         var lines = new StringBuilder ();
348                                         for (int i = 0; i < numErrors; i++) {
349                                                 if (i > 0)
350                                                         lines.Append (", ");
351                                                 lines.Append (errorLines [i]);
352                                         }
353                                         values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionErrorLinesName, lines.ToString ());
354                                 }
355                         } else
356                                 values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionSourceFileName, FormatSourceFile (exc.FileName));
357
358                         if (isCompileException) {
359                                 CompilationException cex = exc as CompilationException;
360                                 StringCollection output = cex.CompilerOutput;
361
362                                 if (output != null && output.Count > 0) {
363                                         pageType |= ExceptionPageTemplateType.CompilerOutput;
364                                         var sb = new StringBuilder ();
365                                         bool first = true;
366                                         foreach (string s in output) {
367                                                 sb.Append (HtmlEncode (s));
368                                                 if (first) {
369                                                         sb.Append ("<br/>");
370                                                         first = false;
371                                                 }
372                                                 sb.Append ("<br/>");
373                                         }
374                                         
375                                         values.Add (ExceptionPageTemplate.Template_HtmlizedExceptionCompilerOutputName, sb.ToString ());
376                                 }
377                         }
378                 }
379                 
380                 void FillDefaultCustomErrorValues (ExceptionPageTemplateValues values)
381                 {
382                         values.Add (ExceptionPageTemplate.Template_PageTitleName, "Runtime Error");
383                         values.Add (ExceptionPageTemplate.Template_ExceptionTypeName, "Runtime Error");
384                         values.Add (ExceptionPageTemplate.Template_ExceptionMessageName, "A runtime error has occurred");
385                         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).");
386                         values.Add (ExceptionPageTemplate.Template_DetailsName, "To enable the details of this specific error message to be viewable, please create a &lt;customErrors&gt; tag within a &quot;web.config&quot; configuration file located in the root directory of the current web application. This &lt;customErrors&gt; tag should then have its &quot;mode&quot; attribute set to &quot;Off&quot;.");
387                 }
388                 
389                 void FillDefaultErrorValues (bool showTrace, bool showExceptionType, Exception baseEx, ExceptionPageTemplateValues values)
390                 {
391                         if (baseEx == null)
392                                 baseEx = this;
393                         
394                         values.Add (ExceptionPageTemplate.Template_PageTitleName, String.Format ("Error{0}", http_code != 0 ? " " + http_code : String.Empty));
395                         values.Add (ExceptionPageTemplate.Template_ExceptionTypeName, showExceptionType ? baseEx.GetType ().ToString () : "Runtime error");
396                         values.Add (ExceptionPageTemplate.Template_ExceptionMessageName, http_code == 404 ? "The resource cannot be found." : HtmlEncode (baseEx.Message));
397
398                         string tmp = http_code != 0 ? "HTTP " + http_code + "." : String.Empty;
399                         values.Add (ExceptionPageTemplate.Template_DescriptionName, tmp + (http_code == 404 ? ERROR_404_DESCRIPTION : HtmlEncode (Description)));
400
401                         if (!String.IsNullOrEmpty (resource_name))
402                                 values.Add (ExceptionPageTemplate.Template_DetailsName, "Requested URL: " + HtmlEncode (resource_name));
403                         else if (http_code == 404)
404                                 values.Add (ExceptionPageTemplate.Template_DetailsName, "No virtual path information available.");
405                         else if (baseEx is HttpException) {
406                                 tmp = ((HttpException)baseEx).Description;
407                                 values.Add (ExceptionPageTemplate.Template_DetailsName, !String.IsNullOrEmpty (tmp) ? HtmlEncode (tmp) : "Web exception occurred but no additional error description given.");
408                         } else {
409                                 var sb = new StringBuilder ("Non-web exception.");
410
411                                 tmp = baseEx.Source;
412                                 if (!String.IsNullOrEmpty (tmp))
413                                         sb.AppendFormat (" Exception origin (name of application or object): {0}.", HtmlEncode (tmp));
414                                 tmp = baseEx.HelpLink;
415                                 if (!String.IsNullOrEmpty (tmp))
416                                         sb.AppendFormat (" Additional information is available at {0}", HtmlEncode (tmp));
417                                 
418                                 values.Add (ExceptionPageTemplate.Template_DetailsName, sb.ToString ());
419                         }
420                         
421                         if (showTrace) {
422                                 string stackTrace = baseEx.StackTrace;
423                                 if (!String.IsNullOrEmpty (stackTrace))
424                                         values.Add (ExceptionPageTemplate.Template_StackTraceName, HtmlEncode (stackTrace));
425                         }
426                 }
427                 
428                 static string HtmlEncode (string s)
429                 {
430                         if (String.IsNullOrEmpty (s))
431                                 return s;
432
433                         string res = HttpUtility.HtmlEncode (s);
434                         return res.Replace ("\r\n", "<br />");
435                 }
436
437                 string FormatSourceFile (string filename)
438                 {
439                         if (filename == null || filename.Length == 0)
440                                 return String.Empty;
441
442                         if (filename.StartsWith ("@@"))
443                                 return "[internal] <!-- " + HttpUtility.HtmlEncode (filename) + " -->";
444
445                         return HttpUtility.HtmlEncode (filename);
446                 }
447                 
448                 static void FormatSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e)
449                 {
450                         if (e is CompilationException)
451                                 WriteCompilationSource (builder, longVersion, e);
452                         else
453                                 WritePageSource (builder, e);
454                 }
455
456                 static void WriteCompilationSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e)
457                 {
458                         int [] a = e.ErrorLines;
459                         string s;
460                         int line = 0;
461                         int index = 0;
462                         int errline = 0;
463
464                         if (a != null && a.Length > 0)
465                                 errline = a [0];
466
467                         int begin = errline - 2;
468                         int end = errline + 2;
469
470                         if (begin < 0)
471                                 begin = 0;
472
473                         string tmp;                     
474                         using (TextReader reader = new StringReader (e.FileText)) {
475                                 while ((s = reader.ReadLine ()) != null) {
476                                         line++;
477                                         if (line < begin || line > end) {
478                                                 if (longVersion != null)
479                                                         longVersion.AppendFormat ("{0}: {1}\r\n", line, HtmlEncode (s));
480                                                 continue;
481                                         }
482                                 
483                                         if (errline == line) {
484                                                 if (longVersion != null)
485                                                         longVersion.Append ("<span class=\"sourceErrorLine\">");
486                                                 builder.Append ("<span class=\"sourceErrorLine\">");
487                                         }
488                                         
489                                         tmp = String.Format ("{0}: {1}\r\n", line, HtmlEncode (s));
490                                         builder.Append (tmp);
491                                         if (longVersion != null)
492                                                 longVersion.Append (tmp);
493                                         
494                                         if (line == errline) {
495                                                 builder.Append ("</span>");
496                                                 if (longVersion != null)
497                                                         longVersion.Append ("</span>");
498                                                 errline = (++index < a.Length) ? a [index] : 0;
499                                         }
500                                 }
501                         }                       
502                 }
503
504                 static void WritePageSource (StringBuilder builder, HtmlizedException e)
505                 {
506                         string s;
507                         int line = 0;
508                         int beginerror = e.ErrorLines [0];
509                         int enderror = e.ErrorLines [1];
510                         int begin = beginerror - 2;
511                         int end = enderror + 2;
512                         if (begin <= 0)
513                                 begin = 1;
514                         
515                         TextReader reader = new StringReader (e.FileText);
516                         while ((s = reader.ReadLine ()) != null) {
517                                 line++;
518                                 if (line < begin)
519                                         continue;
520
521                                 if (line > end)
522                                         break;
523
524                                 if (beginerror == line)
525                                         builder.Append ("<span class=\"sourceErrorLine\">");
526
527                                 builder.AppendFormat ("{0}: {1}\r\n", line, HtmlEncode (s));
528
529                                 if (enderror <= line) {
530                                         builder.Append ("</span>");
531                                         enderror = end + 1; // one shot
532                                 }
533                         }
534                 }
535                 
536                 public int GetHttpCode ()
537                 {
538                         return http_code;
539                 }
540
541                 public static HttpException CreateFromLastError (string message)
542                 {
543                         WebTrace.WriteLine ("CreateFromLastError");
544                         return new HttpException (message, 0);
545                 }
546
547                 // Putting this at the end so that the code above isn't bloated
548                 const string DoubleFaultExceptionMessage = @"<?xml version=""1.0"" encoding=""utf-8""?>
549 <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">
550 <html xmlns=""http://www.w3.org/1999/xhtml"">
551 <head>
552 <style type=""text/css"">
553 body { background-color: #FFFFFF; font-size: .75em; font-family: Verdana, Helvetica, Sans-Serif; margin: 0; padding: 0; color: #696969; }
554 a:link { color: #000000; text-decoration: underline; }
555 a:visited { color: #000000; }
556 a:hover { color: #000000; text-decoration: none; }
557 a:active { color: #12eb87; }
558 p, ul { margin-bottom: 20px; line-height: 1.6em; }
559 pre { font-size: 1.2em; margin-left: 20px; margin-top: 0px; }
560 h1, h2, h3, h4, h5, h6 { font-size: 1.6em; color: #000; font-family: Arial, Helvetica, sans-serif; }
561 h1 { font-weight: bold; margin-bottom: 0; margin-top: 0; padding-bottom: 0; }
562 h2 { font-size: 1em; padding: 0 0 0px 0; color: #696969; font-weight: normal; margin-top: 0; margin-bottom: 20px; }
563 h3 { font-size: 1.2em; }
564 h4 { font-size: 1.1em; }
565 h5, h6 { font-size: 1em; }
566 #header { position: relative; margin-bottom: 0px; color: #000; padding: 0; background-color: #5c87b2; height: 38px; padding-left: 10px; }
567 #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; }
568 #header-image { float: left; padding: 3px; margin-left: 1px; margin-right: 1px; }
569 #header-text { color: #fff; font-size: 1.4em; line-height: 38px; font-weight: bold; }
570 #main { padding: 20px 20px 15px 20px; background-color: #fff; _height: 1px; }
571 #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; }
572 #footer-powered-by { float: right; }
573 .details { font-family: monospace; border: solid 1px #e8eef4; white-space: pre; font-size: 1.2em; overflow: auto; padding: 6px; margin-top: 6px }
574 .details-wrapped { white-space: normal }
575 .details-header { margin-top: 1.5em }
576 .details-header a { font-weight: bold; text-decoration: none }
577 p { margin-bottom: 0.3em; margin-top: 0.1em }
578 .sourceErrorLine { color: #770000; font-weight: bold; }
579 </style>
580
581 <title>Double fault in exception reporting code</title>
582 </head>
583 <body>
584 <h1>Double fault in exception reporting code</h1>
585 <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>
586 </body>
587 </html>
588 ";
589         }
590 }
591