imported patches for pull request spudstuff/u4497

This commit is contained in:
Shannon Deminick
2013-03-11 18:49:45 +06:00
parent 09408b898e
commit fd58017e97
10 changed files with 223 additions and 45 deletions

View File

@@ -1215,6 +1215,40 @@ namespace Umbraco.Core.Configuration
}
}
private static MacroErrorBehaviour? _macroErrorBehaviour;
/// <summary>
/// This configuration setting defines how to handle macro errors:
/// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior)
/// - Silent - Suppress error and hide macro
/// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD)
/// </summary>
/// <value>MacroErrorBehaviour enum defining how to handle macro errors.</value>
public static MacroErrorBehaviour MacroErrorBehaviour
{
get
{
if (_macroErrorBehaviour == null)
{
try
{
var behaviour = MacroErrorBehaviour.Inline;
var value = GetKey("/settings/content/MacroErrors");
if (value != null)
{
Enum<MacroErrorBehaviour>.TryParse(value, true, out behaviour);
}
_macroErrorBehaviour = behaviour;
}
catch (Exception ex)
{
LogHelper.Error<UmbracoSettings>("Could not load /settings/content/MacroErrors from umbracosettings.config", ex);
_macroErrorBehaviour = MacroErrorBehaviour.Inline;
}
}
return _macroErrorBehaviour.Value;
}
}
/// <summary>
/// Configuration regarding webservices

View File

@@ -0,0 +1,23 @@
namespace Umbraco.Core
{
public enum MacroErrorBehaviour
{
/// <summary>
/// Default umbraco behavior - show an inline error within the
/// macro but allow the page to continue rendering.
/// </summary>
Inline,
/// <summary>
/// Silently eat the error and do not display the offending macro.
/// </summary>
Silent,
/// <summary>
/// Throw an exception which can be caught by the global error handler
/// defined in Application_OnError. If no such error handler is defined
/// then you'll see the Yellow Screen Of Death (YSOD) error page.
/// </summary>
Throw
}
}

View File

@@ -71,6 +71,7 @@
<Compile Include="Enum.cs" />
<Compile Include="HashCodeCombiner.cs" />
<Compile Include="IO\FileSystemWrapper.cs" />
<Compile Include="MacroErrorBehaviour.cs" />
<Compile Include="Media\IImageUrlProvider.cs" />
<Compile Include="ObjectResolution\LazyManyObjectsResolverbase.cs" />
<Compile Include="PublishedContentExtensions.cs" />

View File

@@ -86,6 +86,14 @@
<!-- Setting this to true can increase render time for pages with a large number of links -->
<!-- If running Umbraco in virtual directory this *must* be set to true! -->
<ResolveUrlsFromTextString>false</ResolveUrlsFromTextString>
<!-- How Umbraco should handle errors during macro execution. Can be one of the following values:
- inline - show an inline error within the macro but allow the page to continue rendering. Historial Umbraco behaviour.
- silent - Silently suppress the error and do not render the offending macro.
- throw - Throw an exception which can be caught by the global error handler defined in Application_OnError. If no such
error handler is defined then you'll see the Yellow Screen Of Death (YSOD) error page.
Note the error can also be handled by the umbraco.macro.Error event, where you can log/alarm with your own code and change the behaviour per event. -->
<MacroErrors>inline</MacroErrors>
</content>
<security>

View File

@@ -81,6 +81,13 @@
<!-- In seconds. 0 will disable cache -->
<UmbracoLibraryCacheDuration>1800</UmbracoLibraryCacheDuration>
<!-- How Umbraco should handle errors during macro execution. Can be one of the following values:
- inline - show an inline error within the macro but allow the page to continue rendering. Historial Umbraco behaviour.
- silent - Silently suppress the error and do not render the offending macro.
- throw - Throw an exception which can be caught by the global error handler defined in Application_OnError. If no such
error handler is defined then you'll see the Yellow Screen Of Death (YSOD) error page.
Note the error can also be handled by the umbraco.macro.Error event, where you can log/alarm with your own code and change the behaviour per event. -->
<MacroErrors>inline</MacroErrors>
</content>
<security>

View File

@@ -18,17 +18,15 @@ using System.Xml.Xsl;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Web;
using Umbraco.Web.Macros;
using Umbraco.Web.Templates;
using umbraco.BusinessLogic;
using umbraco.BusinessLogic.Utils;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.macro;
using umbraco.cms.businesslogic.member;
using umbraco.DataLayer;
using umbraco.NodeFactory;
using umbraco.presentation.templateControls;
using umbraco.presentation.xslt.Exslt;
using Content = umbraco.cms.businesslogic.Content;
using Macro = umbraco.cms.businesslogic.macro.Macro;
@@ -429,8 +427,25 @@ namespace umbraco
{
renderFailed = true;
Exceptions.Add(e);
LogHelper.WarnWithException<macro>("Error loading userControl (" + Model.TypeName + ")", true, e);
macroControl = new LiteralControl("Error loading userControl '" + Model.TypeName + "'");
LogHelper.WarnWithException<macro>("Error loading userControl (" + Model.TypeName + ")", true, e);
// Invoke any error handlers for this macro
var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.TypeName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour};
OnError(macroErrorEventArgs);
// Check how to handle the error for this macro.
// (note the error event above may have changed the default behaviour as defined in settings)
switch (macroErrorEventArgs.Behaviour)
{
case MacroErrorBehaviour.Inline:
macroControl = new LiteralControl("Error loading userControl '" + Model.TypeName + "'");
break;
case MacroErrorBehaviour.Silent:
macroControl = new LiteralControl("");
break;
case MacroErrorBehaviour.Throw:
throw;
}
break;
}
case (int)MacroTypes.CustomControl:
@@ -451,11 +466,24 @@ namespace umbraco
LogHelper.WarnWithException<macro>("Error loading customControl (Assembly: " +
Model.TypeAssembly +
", Type: '" + Model.TypeName + "'", true, e);
macroControl =
new LiteralControl("Error loading customControl (Assembly: " + Model.TypeAssembly +
", Type: '" +
Model.TypeName + "'");
// Invoke any error handlers for this macro
var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.TypeAssembly, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour};
OnError(macroErrorEventArgs);
// Check how to handle the error for this macro.
// (note the error event above may have changed the default behaviour as defined in settings)
switch (macroErrorEventArgs.Behaviour)
{
case MacroErrorBehaviour.Inline:
macroControl = new LiteralControl("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'");
break;
case MacroErrorBehaviour.Silent:
macroControl = new LiteralControl("");
break;
case MacroErrorBehaviour.Throw:
throw;
}
break;
}
case (int)MacroTypes.XSLT:
@@ -487,24 +515,23 @@ namespace umbraco
true,
e);
var result =
new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")");
/*
string args = "<ul>";
foreach(object key in attributes.Keys)
args += "<li><strong>" + key.ToString() + ": </strong> " + attributes[key] + "</li>";
foreach (object key in pageElements.Keys)
args += "<li><strong>" + key.ToString() + ": </strong> " + pageElements[key] + "</li>";
args += "</ul>";
result.Text += args;
*/
macroControl = result;
// Invoke any error handlers for this macro
var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour};
OnError(macroErrorEventArgs);
// Check how to handle the error for this macro.
// (note the error event above may have changed the default behaviour as defined in settings)
switch (macroErrorEventArgs.Behaviour)
{
case MacroErrorBehaviour.Inline:
macroControl = new LiteralControl("Error loading MacroEngine script (file: " + ScriptFile + ")");
break;
case MacroErrorBehaviour.Silent:
macroControl = new LiteralControl("");
break;
case MacroErrorBehaviour.Throw:
throw;
}
break;
}
default:
@@ -801,7 +828,26 @@ namespace umbraco
{
Exceptions.Add(e);
LogHelper.WarnWithException<macro>("Error loading XSLT " + Model.Xslt, true, e);
return new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile);
Control macroControl = null;
// Invoke any error handlers for this macro
var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, File = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour};
OnError(macroErrorEventArgs);
// Check how to handle the error for this macro.
// (note the error event above may have changed the default behaviour as defined in settings)
switch (macroErrorEventArgs.Behaviour)
{
case MacroErrorBehaviour.Inline:
macroControl = new LiteralControl("Error reading XSLT file: \\xslt\\" + XsltFile);
break;
case MacroErrorBehaviour.Silent:
macroControl = new LiteralControl("");
break;
case MacroErrorBehaviour.Throw:
throw;
}
return macroControl;
}
}
}
@@ -1505,7 +1551,7 @@ namespace umbraco
}
if (!File.Exists(IOHelper.MapPath(userControlPath)))
return new LiteralControl(string.Format("UserControl {0} does not exist.", fileName));
throw new UmbracoException(string.Format("UserControl {0} does not exist.", fileName));
var oControl = (UserControl)new UserControl().LoadControl(userControlPath);
@@ -1531,11 +1577,7 @@ namespace umbraco
catch (Exception e)
{
LogHelper.WarnWithException<macro>(string.Format("Error creating usercontrol ({0})", fileName), true, e);
return new LiteralControl(
string.Format(
"<div style=\"color: black; padding: 3px; border: 2px solid red\"><b style=\"color:red\">Error creating control ({0}).</b><br/> Maybe file doesn't exists or the usercontrol has a cache directive, which is not allowed! See the tracestack for more information!</div>",
fileName));
throw;
}
}
@@ -1802,5 +1844,31 @@ namespace umbraco
value = false;
return false;
}
#region Events
/// <summary>
/// The macro error event handler.
/// </summary>
public delegate void ErrorEventHandler(object sender, MacroErrorEventArgs e);
/// <summary>
/// Occurs when a macro error is raised.
/// </summary>
public static event ErrorEventHandler Error;
/// <summary>
/// Raises the <see cref="E:Error"/> event.
/// </summary>
/// <param name="e">The <see cref="MacroErrorEventArgs"/> instance containing the event data.</param>
protected virtual void OnError(MacroErrorEventArgs e)
{
if (Error != null)
{
Error(this, e);
}
}
#endregion
}
}

View File

@@ -183,6 +183,7 @@ namespace umbraco.presentation.templateControls
System.Web.HttpContext.Current.Trace.Warn("Template", "Result of macro " + tempMacro.Name + " is null");
} catch (Exception ee) {
System.Web.HttpContext.Current.Trace.Warn("Template", "Error adding macro " + tempMacro.Name, ee);
throw;
}
}
}

View File

@@ -171,11 +171,7 @@ namespace umbraco.MacroEngines
Success = false;
ResultException = exception;
HttpContext.Current.Trace.Warn("umbracoMacro", string.Format("Error Loading Razor Script (file: {0}) {1} {2}", macro.Name, exception.Message, exception.StackTrace));
var loading = string.Format("<div style=\"border: 1px solid #990000\">Error loading Razor Script {0}</br/>", macro.ScriptName);
if (GlobalSettings.DebugMode)
loading = loading + exception.Message;
loading = loading + "</div>";
return loading;
throw;
}
}

View File

@@ -1,11 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Xml;
using umbraco.BusinessLogic;
using Umbraco.Core;
using System.Collections.Generic;
using umbraco.MacroEngines;
@@ -554,6 +550,18 @@ namespace umbraco
get { return Umbraco.Core.Configuration.UmbracoSettings.ResolveUrlsFromTextString; }
}
/// <summary>
/// This configuration setting defines how to handle macro errors:
/// - Inline - Show error within macro as text (default and current Umbraco 'normal' behavior)
/// - Silent - Suppress error and hide macro
/// - Throw - Throw an exception and invoke the global error handler (if one is defined, if not you'll get a YSOD)
/// </summary>
/// <value>MacroErrorBehaviour enum defining how to handle macro errors.</value>
public static MacroErrorBehaviour MacroErrorBehaviour
{
get { return Umbraco.Core.Configuration.UmbracoSettings.MacroErrorBehaviour; }
}
/// <summary>
/// Configuration regarding webservices
/// </summary>

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Umbraco.Core;
using umbraco.cms.businesslogic.member;
using umbraco.cms.businesslogic.web;
@@ -61,5 +62,36 @@ namespace umbraco.cms.businesslogic {
{
public bool CancelChildren { get; set; }
}
// Provides information on the macro that caused an error
public class MacroErrorEventArgs : System.EventArgs
{
/// <summary>
/// Name of the faulting macro.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Alias of the faulting macro.
/// </summary>
public string Alias { get; set; }
/// <summary>
/// Filename of the faulting macro.
/// </summary>
public string File { get; set; }
/// <summary>
/// Exception raised.
/// </summary>
public Exception Exception { get; set; }
/// <summary>
/// Gets or sets the desired behaviour when a matching macro causes an error. See
/// <see cref="MacroErrorBehaviour"/> for definitions. By setting this in your event
/// you can override the default behaviour defined in UmbracoSettings.config.
/// </summary>
/// <value>Macro error behaviour enum.</value>
public MacroErrorBehaviour Behaviour { get; set; }
}
}