Fixing an issue with output parameters that are of type IntPtr
[castle.git] / MonoRail / Castle.MonoRail.Framework / Extensions / ExceptionChaining / AbstractExceptionHandler.cs
blob1dbfca8507c64c3b79c0a3203a518f647b6bab0b
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.Framework.Extensions.ExceptionChaining
17 using System;
18 using System.Collections;
19 using System.Collections.Specialized;
20 using System.Text;
22 /// <summary>
23 /// Provides a basic implementation of <see cref="IExceptionHandler"/>
24 /// </summary>
25 public abstract class AbstractExceptionHandler : IExceptionHandler
27 private IExceptionHandler nextHandler;
29 /// <summary>
30 /// Implementors should perform any required
31 /// initialization
32 /// </summary>
33 public virtual void Initialize()
37 /// <summary>
38 /// Implementors should perform the action
39 /// on the exception. Note that the exception
40 /// is available in <see cref="IEngineContext.LastException"/>
41 /// </summary>
42 /// <param name="context"></param>
43 public abstract void Process(IEngineContext context);
45 /// <summary>
46 /// The next exception in the sink
47 /// or null if none exists.
48 /// </summary>
49 /// <value></value>
50 public IExceptionHandler Next
52 get { return nextHandler; }
53 set { nextHandler = value; }
56 /// <summary>
57 /// Invokes the next handler.
58 /// </summary>
59 /// <param name="context">The context.</param>
60 protected void InvokeNext(IEngineContext context)
62 if (nextHandler != null)
64 nextHandler.Process(context);
68 /// <summary>
69 /// Builds the standard message.
70 /// </summary>
71 /// <param name="context">The context.</param>
72 /// <returns></returns>
73 protected string BuildStandardMessage(IEngineContext context)
75 StringBuilder sbMessage = new StringBuilder();
77 sbMessage.Append("Controller details\r\n");
78 sbMessage.Append("==================\r\n\r\n");
79 sbMessage.AppendFormat("Url {0}\r\n", context.Request.Url);
80 sbMessage.AppendFormat("Area {0}\r\n", context.UrlInfo.Area);
81 sbMessage.AppendFormat("Controller {0}\r\n", context.UrlInfo.Controller);
82 sbMessage.AppendFormat("Action {0}\r\n", context.UrlInfo.Action);
83 sbMessage.AppendFormat("Extension {0}\r\n\r\n", context.UrlInfo.Extension);
85 sbMessage.Append("Exception details\r\n");
86 sbMessage.Append("=================\r\n\r\n");
87 sbMessage.AppendFormat("Exception occured at {0}\r\n", DateTime.Now);
88 RecursiveDumpException(context.LastException, sbMessage, 0);
90 sbMessage.Append("\r\nEnvironment and params");
91 sbMessage.Append("\r\n======================\r\n\r\n");
92 sbMessage.AppendFormat("Machine {0}\r\n", Environment.MachineName);
93 sbMessage.AppendFormat("ApplicationPath {0}\r\n", context.ApplicationPath);
94 // sbMessage.AppendFormat("ApplicationPhysicalPath {0}\r\n", context.ApplicationPhysicalPath);
95 sbMessage.AppendFormat("HttpMethod {0}\r\n", context.Request.HttpMethod);
96 sbMessage.AppendFormat("UrlReferrer {0}\r\n", context.Request.UrlReferrer);
98 if (context.CurrentUser != null)
100 sbMessage.AppendFormat("CurrentUser.Name {0}\r\n", context.CurrentUser.Identity.Name);
101 sbMessage.AppendFormat("CurrentUser.AuthenticationType {0}\r\n", context.CurrentUser.Identity.AuthenticationType);
102 sbMessage.AppendFormat("CurrentUser.IsAuthenticated {0}\r\n", context.CurrentUser.Identity.IsAuthenticated);
105 DumpDictionary(context.Flash, "Flash", sbMessage);
106 DumpDictionary(context.Request.QueryString, "QueryString", sbMessage);
107 DumpDictionary(context.Request.Form, "Form", sbMessage);
108 DumpDictionary(context.Session, "Session", sbMessage);
110 return sbMessage.ToString();
113 private void DumpDictionary(IDictionary dict, String title, StringBuilder message)
115 if (dict == null || dict.Count == 0)
117 return;
120 message.AppendFormat("{0}: \r\n", title);
124 foreach(DictionaryEntry entry in dict)
126 message.AppendFormat("\r\n\t{0}:{1}", entry.Key, entry.Value);
129 catch(Exception)
131 // Ignores
135 private void DumpDictionary(NameValueCollection dict, String title, StringBuilder message)
137 if (dict == null || dict.Count == 0)
139 return;
142 message.AppendFormat("{0}: \r\n", title);
146 foreach(String key in dict.Keys)
148 message.AppendFormat("\r\n\t{0}:{1} \r\n", key, dict[key]);
151 catch(Exception)
153 // Ignores
157 private void RecursiveDumpException(Exception exception, StringBuilder message, int nested)
159 if (exception == null) return;
161 char[] spaceBuff = new char[nested * 2];
162 for(int i = 0; i < nested * 2; i++) spaceBuff[i] = ' ';
164 String space = new String(spaceBuff);
166 message.AppendFormat("{0}Exception: {1}\r\n", space, exception.Message);
167 message.AppendFormat("{0}Stack Trace:\r\n{0}{1}\r\n", space, exception.StackTrace);
169 RecursiveDumpException(exception.InnerException, message, nested + 1);