2009-07-28 Gonzalo Paniagua Javier <gonzalo@novell.com>
[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 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.Collections.Specialized;
40
41 namespace System.Web
42 {
43         // CAS
44         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
46 #if NET_2_0
47         [Serializable]
48 #endif
49         public class HttpException : ExternalException
50         {
51                 const string DEFAULT_DESCRIPTION_TEXT = "Error processing request.";
52                 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.";
53                 
54                 int http_code = 500;
55                 string resource_name;
56                 string description;
57                 
58                 const string errorStyleFonts = "\"Verdana\",\"DejaVu Sans\",sans-serif";
59                 
60                 public HttpException ()
61                 {
62                 }
63
64                 public HttpException (string message)
65                         : base (message)
66                 {
67                 }
68
69                 public HttpException (string message, Exception innerException)
70                         : base (message, innerException)
71                 {
72                 }
73
74                 public HttpException (int httpCode, string message) : base (message)
75                 {
76                         http_code = httpCode;
77                 }
78
79                 internal HttpException (int httpCode, string message, string resourceName) : this (httpCode, message)
80                 {
81                         resource_name = resourceName;
82                 }
83
84                 internal HttpException (int httpCode, string message, string resourceName, string description) : this (httpCode, message, resourceName)
85                 {
86                         this.description = description;
87                 }
88                 
89 #if NET_2_0
90                 protected
91 #else
92                 internal
93 #endif
94                 HttpException (SerializationInfo info, StreamingContext context)
95                         : base (info, context)
96                 {
97                         http_code = info.GetInt32 ("_httpCode");
98                 }
99
100 #if NET_2_0
101                 [SecurityPermission (SecurityAction.Demand, SerializationFormatter = true)]
102                 public override void GetObjectData (SerializationInfo info, StreamingContext context)
103                 {
104                         base.GetObjectData (info, context);
105                         info.AddValue ("_httpCode", http_code);
106                 }
107 #endif
108
109                 public HttpException (int httpCode, string message, int hr) 
110                         : base (message, hr)
111                 {
112                         http_code = httpCode;
113                 }
114
115                 public HttpException (string message, int hr)
116                         : base (message, hr)
117                 {
118                 }
119         
120                 public HttpException (int httpCode, string message, Exception innerException)
121                         : base (message, innerException)
122                 {
123                         http_code = httpCode;
124                 }
125
126                 internal HttpException (int httpCode, string message, Exception innerException, string resourceName)
127                         : this (httpCode, message, innerException)
128                 {
129                         resource_name = resourceName;
130                 }
131                 
132                 public string GetHtmlErrorMessage ()
133                 {
134                         try {
135                                 HttpContext ctx = HttpContext.Current;
136                                 if (ctx != null && ctx.IsCustomErrorEnabled) {
137                                         if (http_code != 404 && http_code != 403)
138                                                 return GetCustomErrorDefaultMessage ();
139                                         else
140                                                 return GetDefaultErrorMessage (false);
141                                 }
142                                 
143                                 if (!(this.InnerException is HtmlizedException))
144                                         return GetDefaultErrorMessage (true);
145                                 
146                                 return GetHtmlizedErrorMessage ();
147                         } catch (Exception ex) {
148                                 Console.WriteLine (ex);
149                                 
150                                 // we need the try/catch block in case the
151                                 // problem was with MapPath, which will cause
152                                 // IsCustomErrorEnabled to throw an exception
153                                 return GetCustomErrorDefaultMessage ();
154                         }
155                 }
156
157                 internal virtual string Description {
158                         get {
159                                 if (description != null)
160                                         return description;
161
162                                 return DEFAULT_DESCRIPTION_TEXT;
163                         }
164                         
165                         set {
166                                 if (value != null && value.Length > 0)
167                                         description = value;
168                                 else
169                                         description = DEFAULT_DESCRIPTION_TEXT;
170                         }
171                 }
172
173                 void WriteFileTop (StringBuilder builder, string title)
174                 {
175 #if TARGET_J2EE
176                         builder.AppendFormat ("<html><head><title>{0}</title><style type=\"text/css\">", title);
177                         builder.AppendFormat (
178                                 @"body {{font-family:{0};font-weight:normal;font-size: 9pt;color:black;background-color: white}}
179 p {{font-family:{0};font-weight:normal;color:black;margin-top: -5px}}
180 b {{font-family:{0};font-weight:bold;color:black;margin-top: -5px}}
181 h1 {{ font-family:{0};font-weight:normal;font-size:18pt;color:red }}
182 h2 {{ font-family:{0};font-weight:normal;font-size:14pt;color:maroon }}
183 pre {{font-family:""Lucida Console"",""DejaVu Sans Mono"",monospace;font-size: 10pt}}
184 div.bodyText {{font-family: {0}}}
185 table.sampleCode {{width: 100%; background-color: #ffffcc; }}
186 .errorText {{color: red; font-weight: bold}}
187 .marker {{font-weight: bold; color: black;text-decoration: none;}}
188 .version {{color: gray;}}
189 .error {{margin-bottom: 10px;}}
190 .expandable {{ text-decoration:underline; font-weight:bold; color:navy; cursor:pointer; }}", errorStyleFonts);
191 #else
192                         builder.Append ("<?xml version=\"1.0\" ?>\n");
193                         builder.Append ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
194                         builder.AppendFormat ("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"><head><title>{0}</title><style type=\"text/css\">", title);
195                         builder.AppendFormat (
196                                 @"body {{font-family:{0};font-weight:normal;font-size: .7em;color:black;background-color: white}}
197 p {{font-family:{0};font-weight:normal;color:black;margin-top: -5px}}
198 b {{font-family:{0};font-weight:bold;color:black;margin-top: -5px}}
199 h1 {{ font-family:{0};font-weight:normal;font-size:18pt;color:red }}
200 h2 {{ font-family:{0};font-weight:normal;font-size:14pt;color:maroon }}
201 pre,code {{font-family:""Lucida Console"",""DejaVu Sans Mono"",monospace;font-size: 0.9em,white-space: pre-line}}
202 div.bodyText {{font-family: {0}}}
203 table.sampleCode {{width: 100%; background-color: #ffffcc; }}
204 .errorText {{color: red; font-weight: bold}}
205 .marker {{font-weight: bold; color: black;text-decoration: none;}}
206 .version {{color: gray;}}
207 .error {{margin-bottom: 10px;}}
208 .expandable {{ text-decoration:underline; font-weight:bold; color:navy; cursor:pointer; }}", errorStyleFonts);
209 #endif
210
211                         builder.AppendFormat (
212                                 "</style></head><body><h1>Server Error in '{0}' Application</h1><hr style=\"color: silver\"/>",
213                                 HtmlEncode (HttpRuntime.AppDomainAppVirtualPath));
214                 }
215                 
216                 void WriteFileBottom (StringBuilder builder, bool showTrace)
217                 {
218                         if (showTrace) {
219                                 builder.Append ("<hr style=\"color: silver\"/>");
220                                 builder.AppendFormat ("<strong>Version information: </strong> Mono Version: {0}; ASP.NET Version: {0}</body></html>\r\n", Environment.Version);
221                         
222                                 string trace, message;
223                                 bool haveTrace;
224                                 Exception ex = this;
225
226                                 builder.Append ("\r\n<!--");
227                                 while (ex != null) {
228                                         trace = ex.StackTrace;
229                                         message = ex.Message;
230                                         haveTrace = (trace != null && trace.Length > 0);
231                                 
232                                         if (!haveTrace && (message == null || message.Length == 0)) {
233                                                 ex = ex.InnerException;
234                                                 continue;
235                                         }
236
237                                         builder.Append ("\r\n[" + ex.GetType () + "]: " + HtmlEncode (message) + "\r\n");
238                                         if (haveTrace)
239                                                 builder.Append (ex.StackTrace);
240                                 
241                                         ex = ex.InnerException;
242                                 }
243                         
244                                 builder.Append ("\r\n-->");
245                         } else
246                                 builder.Append ("</body></html>\r\n");
247                 }
248
249                 string GetCustomErrorDefaultMessage ()
250                 {
251                         StringBuilder builder = new StringBuilder ();
252                         WriteFileTop (builder, "Runtime Error");
253 #if TARGET_J2EE //on portal we cannot know if we run locally
254                         if (!HttpContext.Current.IsServletRequest)
255                                 builder.Append (
256 @"<p><strong>Description:</strong> 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).</p>
257 <p><strong>Details:</strong> 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;.</p>
258 <table class=""sampleCode""><tr><td><pre>
259
260 &lt;!-- Web.Config Configuration File --&gt;
261
262 &lt;configuration&gt;
263     &lt;system.web&gt;
264
265         &lt;customErrors mode=&quot;Off&quot;/&gt;
266     &lt;/system.web&gt;
267 &lt;/configuration&gt;</pre>
268     </td></tr></table><br/>
269 ");
270                         else
271 #endif
272                         builder.Append (@"<p><strong>Description:</strong> 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 remotely (for security reasons)." + (
273                                 " It could, however, be viewed by browsers running on the local server machine.") 
274                                 + @"</p>
275 <p><strong>Details:</strong> To enable the details of this specific error message to be viewable on remote machines, 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;.</p>
276 <table class=""sampleCode""><tr><td><pre>
277
278 &lt;!-- Web.Config Configuration File --&gt;
279
280 &lt;configuration&gt;
281     &lt;system.web&gt;
282
283         &lt;customErrors mode=&quot;Off&quot;/&gt;
284     &lt;/system.web&gt;
285 &lt;/configuration&gt;</pre>
286     </td></tr></table><br/>
287 <p><strong>Notes:</strong> The current error page you are seeing can be replaced by a custom error page by modifying the &quot;defaultRedirect&quot; attribute of the application's &lt;customErrors&gt; configuration tag to point to a custom error page URL.</p>
288 <table class=""sampleCode""><tr><td><pre>
289 &lt;!-- Web.Config Configuration File --&gt;
290
291 &lt;configuration&gt;
292     &lt;system.web&gt;
293         &lt;customErrors mode=&quot;RemoteOnly&quot; defaultRedirect=&quot;mycustompage.htm&quot;/&gt;
294
295     &lt;/system.web&gt;
296 &lt;/configuration&gt;</pre></td></tr></table>");
297                         WriteFileBottom (builder, false);
298                         return builder.ToString ();
299                 }
300                 
301                 string GetDefaultErrorMessage (bool showTrace)
302                 {
303                         Exception ex, baseEx;
304                         ex = baseEx = GetBaseException ();
305                         if (ex == null)
306                                 ex = this;
307
308                         StringBuilder builder = new StringBuilder ();
309                         WriteFileTop (builder, String.Format ("Error{0}", http_code != 0 ? " " + http_code : String.Empty));
310                         builder.Append ("<h2><em>");
311                         if (http_code == 404)
312                                 builder.Append ("The resource cannot be found.");
313                         else
314                                 builder.Append (HtmlEncode (ex.Message));
315                         builder.Append ("</em></h2>\r\n<p><strong>Description: </strong>");
316                         
317                         if (http_code != 0)
318                                 builder.AppendFormat ("HTTP {0}. ", http_code);
319                         builder.Append (http_code == 404 ? ERROR_404_DESCRIPTION : HtmlEncode (Description));
320                         builder.Append ("</p>\r\n");
321
322                         if (resource_name != null && resource_name.Length > 0)
323                                 builder.AppendFormat ("<p><strong>Requested URL: </strong>{0}</p>\r\n", resource_name);
324                         
325                         if (showTrace && baseEx != null && http_code != 404 && http_code != 403) {
326                                 builder.Append ("<p><strong>Stack Trace: </strong></p>");
327                                 builder.Append ("<table summary=\"Stack Trace\" class=\"sampleCode\">\r\n<tr><td>");
328                                 WriteTextAsCode (builder, baseEx.ToString ());
329                                 builder.Append ("</td></tr>\r\n</table>\r\n");
330                         }
331                         WriteFileBottom (builder, showTrace);
332                         
333                         return builder.ToString ();
334                 }
335
336                 static string HtmlEncode (string s)
337                 {
338                         if (s == null)
339                                 return s;
340
341                         string res = HttpUtility.HtmlEncode (s);
342                         return res.Replace ("\r\n", "<br />");
343                 }
344
345                 string FormatSourceFile (string filename)
346                 {
347                         if (filename == null || filename.Length == 0)
348                                 return String.Empty;
349
350                         if (filename.StartsWith ("@@"))
351                                 return "[internal] <!-- " + filename + " -->";
352
353                         return filename;
354                 }
355                 
356                 string GetHtmlizedErrorMessage ()
357                 {
358                         StringBuilder builder = new StringBuilder ();
359                         HtmlizedException exc = (HtmlizedException) this.InnerException;
360 #if TARGET_J2EE
361                         bool isParseException = false;
362                         bool isCompileException = false;
363 #else
364                         bool isParseException = exc is ParseException;
365                         bool isCompileException = (!isParseException && exc is CompilationException);
366 #endif
367                         
368                         WriteFileTop (builder, exc.Title);
369                         builder.AppendFormat ("<h2><em>{0}</em></h2>\r\n", exc.Title);
370                         builder.AppendFormat ("<p><strong>Description: </strong>{0}\r\n</p>\r\n", HtmlEncode (exc.Description));
371                         string errorMessage = HtmlEncode (exc.ErrorMessage);
372                         
373                         builder.Append ("<p><strong>");
374                         if (isParseException)
375                                 builder.Append ("Parser ");
376                         else if (isCompileException)
377                                 builder.Append ("Compiler ");
378                         
379                         builder.Append ("Error Message: </strong>");
380 #if NET_2_0
381                         builder.AppendFormat ("<code>{0}</code></p>", errorMessage);
382 #else
383                         builder.AppendFormat ("<blockquote><pre>{0}</pre></blockquote></p>", errorMessage);
384 #endif
385
386                         StringBuilder longCodeVersion = null;
387                         
388                         if (exc.FileText != null) {
389                                 if (isParseException || isCompileException) {
390                                         builder.Append ("<p><strong>Source Error: </strong></p>\r\n");
391                                         builder.Append ("<table summary=\"Source error\" class=\"sampleCode\">\r\n<tr><td>");
392
393                                         if (isCompileException)
394                                                 longCodeVersion = new StringBuilder ();
395                                         WriteSource (builder, longCodeVersion, exc);
396                                         builder.Append ("</pre></code></td></tr>\r\n</table>\r\n");
397                                 } else {
398                                         builder.Append ("<table summary=\"Source file\" class=\"sampleCode\">\r\n<tr><td>");
399                                         WriteSource (builder, null, exc);
400                                         builder.Append ("</pre></code></td></tr>\r\n</table>\r\n");
401                                 }
402
403                                 builder.Append ("<br/><p><strong>Source File: </strong>");
404                                 if (exc.SourceFile != exc.FileName)
405                                         builder.Append (FormatSourceFile (exc.SourceFile));
406                                 else
407                                         builder.Append (FormatSourceFile (exc.FileName));
408
409                                 if (isParseException || isCompileException) {
410                                         int[] errorLines = exc.ErrorLines;
411                                         int numErrors = errorLines != null ? errorLines.Length : 0;
412                                         if (numErrors > 0) {
413                                                 builder.AppendFormat ("&nbsp;&nbsp;<strong>Line{0}: </strong>", numErrors > 1 ? "s" : String.Empty);
414                                                 for (int i = 0; i < numErrors; i++) {
415                                                         if (i > 0)
416                                                                 builder.Append (", ");
417                                                         builder.Append (exc.ErrorLines [i]);
418                                                 }
419                                         }
420                                 }
421                                 builder.Append ("</p>");
422                         } else if (exc.FileName != null)
423                                 builder.AppendFormat ("{0}</p>", HtmlEncode (exc.FileName));
424
425                         bool needToggleJS = false;
426                         
427 #if !TARGET_J2EE
428                         if (isCompileException) {
429                                 CompilationException cex = exc as CompilationException;
430                                 StringCollection output = cex.CompilerOutput;
431
432                                 if (output != null && output.Count > 0) {
433                                         needToggleJS = true;
434                                         StringBuilder sb = new StringBuilder ();
435                                         foreach (string s in output)
436                                                 sb.Append (s + "\r\n");
437                                         WriteExpandableBlock (builder, "compilerOutput", "Show Detailed Compiler Output", sb.ToString ());
438                                 }
439                         }
440 #endif
441                         
442                         if (longCodeVersion != null && longCodeVersion.Length > 0) {
443                                 WriteExpandableBlock (builder, "fullCode", "Show Complete Compilation Source", longCodeVersion.ToString ());
444                                 needToggleJS = true;
445                         }
446
447                         if (needToggleJS)
448                                 builder.Append ("<script type=\"text/javascript\">\r\n" +
449                                                 "function ToggleVisible (id)\r\n" +
450                                                 "{\r\n" +
451                                                 "\tvar e = document.getElementById (id);\r\n" +
452                                                 "\tif (e.style.display == 'none')\r\n" +
453                                                 "\t{\r\n" +
454                                                 "\t\te.style.display = '';\r\n" +
455                                                 "\t} else {\r\n" +
456                                                 "\t\te.style.display = 'none';\r\n" +
457                                                 "\t}\r\n" +
458                                                 "}\r\n" +
459                                                 "</script>\r\n");
460                         
461                         WriteFileBottom (builder, true);
462                         
463                         return builder.ToString ();
464                 }
465
466                 static void WriteExpandableBlock (StringBuilder builder, string id, string title, string contents)
467                 {
468                         builder.AppendFormat ("<br><div class=\"expandable\" onclick=\"ToggleVisible ('{1}')\">{0}:</div><br/>" +
469                                               "<div id=\"{1}\" style=\"display: none\"><table summary=\"Details\" class=\"sampleCode\"><tr><td>" +
470                                               "<code><pre>\r\n", title, id);
471                         builder.Append (contents);
472                         builder.Append ("</pre></code></td></tr></table></div>");
473                 }
474                 
475                 static void WriteTextAsCode (StringBuilder builder, string text)
476                 {
477                         builder.AppendFormat ("<pre>{0}</pre>", HtmlEncode (text));
478                 }
479
480 #if TARGET_J2EE
481                 static void WriteSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e)
482                 {
483                         builder.Append ("<code><pre>");
484                         WritePageSource (builder, e);
485                         builder.Append ("</code></pre>\r\n");
486                 }
487
488 #else
489                 static void WriteSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e)
490                 {
491                         builder.Append ("<code><pre>");
492                         if (e is CompilationException)
493                                 WriteCompilationSource (builder, longVersion, e);
494                         else
495                                 WritePageSource (builder, e);
496
497                         builder.Append ("<code></pre>\r\n");
498                 }
499 #endif
500                 
501                 static void WriteCompilationSource (StringBuilder builder, StringBuilder longVersion, HtmlizedException e)
502                 {
503                         int [] a = e.ErrorLines;
504                         string s;
505                         int line = 0;
506                         int index = 0;
507                         int errline = 0;
508
509                         if (a != null && a.Length > 0)
510                                 errline = a [0];
511
512                         int begin = errline - 2;
513                         int end = errline + 2;
514
515                         if (begin < 0)
516                                 begin = 0;
517
518                         string tmp;                     
519                         using (TextReader reader = new StringReader (e.FileText)) {
520                                 while ((s = reader.ReadLine ()) != null) {
521                                         line++;
522                                         if (line < begin || line > end) {
523                                                 if (longVersion != null)
524                                                         longVersion.AppendFormat ("Line {0}: {1}\r\n", line, HtmlEncode (s));
525                                                 continue;
526                                         }
527                                 
528                                         if (errline == line) {
529                                                 if (longVersion != null)
530                                                         longVersion.Append ("<span style=\"color: red\">");
531                                                 builder.Append ("<span style=\"color: red\">");
532                                         }
533                                         
534                                         tmp = String.Format ("Line {0}: {1}\r\n", line, HtmlEncode (s));
535                                         builder.Append (tmp);
536                                         if (longVersion != null)
537                                                 longVersion.Append (tmp);
538                                         
539                                         if (line == errline) {
540                                                 builder.Append ("</span>");
541                                                 if (longVersion != null)
542                                                         longVersion.Append ("</span>");
543                                                 errline = (++index < a.Length) ? a [index] : 0;
544                                         }
545                                 }
546                         }                       
547                 }
548
549                 static void WritePageSource (StringBuilder builder, HtmlizedException e)
550                 {
551                         string s;
552                         int line = 0;
553                         int beginerror = e.ErrorLines [0];
554                         int enderror = e.ErrorLines [1];
555                         int begin = beginerror - 2;
556                         int end = enderror + 2;
557                         if (begin <= 0)
558                                 begin = 1;
559                         
560                         TextReader reader = new StringReader (e.FileText);
561                         while ((s = reader.ReadLine ()) != null) {
562                                 line++;
563                                 if (line < begin)
564                                         continue;
565
566                                 if (line > end)
567                                         break;
568
569                                 if (beginerror == line)
570                                         builder.Append ("<span style=\"color: red\">");
571
572                                 builder.AppendFormat ("Line {0}: {1}\r\n", line, HtmlEncode (s));
573
574                                 if (enderror <= line) {
575                                         builder.Append ("</span>");
576                                         enderror = end + 1; // one shot
577                                 }
578                         }
579                 }
580                 
581                 public int GetHttpCode ()
582                 {
583                         return http_code;
584                 }
585
586                 public static HttpException CreateFromLastError (string message)
587                 {
588                         WebTrace.WriteLine ("CreateFromLastError");
589                         return new HttpException (message, 0);
590                 }
591         }
592 }
593