1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
18 using System
.Collections
;
19 using System
.Collections
.Specialized
;
23 /// Provides a basic implementation of <see cref="IExceptionHandler"/>
25 public abstract class AbstractExceptionHandler
: IExceptionHandler
27 private IExceptionHandler nextHandler
;
30 /// Implementors should perform any required
33 public virtual void Initialize()
38 /// Implementors should perform the action
39 /// on the exception. Note that the exception
40 /// is available in <see cref="IEngineContext.LastException"/>
42 /// <param name="context"></param>
43 public abstract void Process(IEngineContext context
);
46 /// The next exception in the sink
47 /// or null if none exists.
50 public IExceptionHandler Next
52 get { return nextHandler; }
53 set { nextHandler = value; }
57 /// Invokes the next handler.
59 /// <param name="context">The context.</param>
60 protected void InvokeNext(IEngineContext context
)
62 if (nextHandler
!= null)
64 nextHandler
.Process(context
);
69 /// Builds the standard message.
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)
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
);
135 private void DumpDictionary(NameValueCollection dict
, String title
, StringBuilder message
)
137 if (dict
== null || dict
.Count
== 0)
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
]);
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);