Exemple #1
0
        /// <summary>
        /// Raises the error event and based on the error behavior either return a control to display or throw the exception
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        private Control GetControlForErrorBehavior(string msg, MacroErrorEventArgs args)
        {
            OnError(args);

            switch (args.Behaviour)
            {
                case MacroErrorBehaviour.Inline:
                    return new LiteralControl(msg);
                case MacroErrorBehaviour.Silent:
                    return new LiteralControl("");
                case MacroErrorBehaviour.Throw:
                default:
                    return null;
            }
        }
Exemple #2
0
        // gets the control for the macro, using GetXsltTransform methods for execution
        // will pick XmlDocument or Navigator mode depending on the capabilities of the published caches
        internal Control LoadMacroXslt(macro macro, MacroModel model, Hashtable pageElements, bool throwError)
        {
            if (XsltFile.Trim() == string.Empty)
            {
                TraceWarn("macro", "Xslt is empty");
                return new LiteralControl(string.Empty);
            }

            using (DisposableTimer.DebugDuration<macro>("Executing XSLT: " + XsltFile))
            {
                XmlDocument macroXml = null;

                // get master xml document
                var cache = UmbracoContext.Current.ContentCache.InnerCache as Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedContentCache;
                if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
                XmlDocument umbracoXml = cache.GetXml(UmbracoContext.Current, UmbracoContext.Current.InPreviewMode);
                macroXml = new XmlDocument();
                macroXml.LoadXml("<macro/>");
                foreach (var prop in macro.Model.Properties)
                {
                    AddMacroXmlNode(umbracoXml, macroXml, prop.Key, prop.Type, prop.Value);
                }

                if (HttpContext.Current.Request.QueryString["umbDebug"] != null && GlobalSettings.DebugMode)
                {
                    var outerXml = macroXml.OuterXml;
                    return
                        new LiteralControl("<div style=\"border: 2px solid green; padding: 5px;\"><b>Debug from " +
                                           macro.Name +
                                           "</b><br/><p>" + HttpContext.Current.Server.HtmlEncode(outerXml) +
                                           "</p></div>");
                }

                try
                {
                    var xsltFile = getXslt(XsltFile);

                    using (DisposableTimer.DebugDuration<macro>("Performing transformation"))
                    {
                        try
                        {
                            var transformed = GetXsltTransformResult(macroXml, xsltFile);
                            var result = CreateControlsFromText(transformed);

                            return result;
                        }
                        catch (Exception e)
                        {
                            Exceptions.Add(e);
                            LogHelper.WarnWithException<macro>("Error parsing XSLT file", e);
                            
                            var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                            var macroControl = GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs);
                            //if it is null, then we are supposed to throw the (original) exception
                            // see: http://issues.umbraco.org/issue/U4-497 at the end
                            if (macroControl == null && throwError)
                            {
                                throw;
                            }
                            return macroControl;
                        }   
                    }                    
                }
                catch (Exception e)
                {
                    Exceptions.Add(e);
                    LogHelper.WarnWithException<macro>("Error loading XSLT " + Model.Xslt, true, e);

                    // Invoke any error handlers for this macro
                    var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                    var macroControl = GetControlForErrorBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs);
                    //if it is null, then we are supposed to throw the (original) exception
                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                    if (macroControl == null && throwError)
                    {
                        throw;
                    }
                    return macroControl;
                }
            }            
        }
Exemple #3
0
        public Control renderMacro(Hashtable pageElements, int pageId)
        {
            var macroInfo = (Model.MacroType == MacroTypes.Script && Model.Name.IsNullOrWhiteSpace())
                                ? string.Format("Render Inline Macro, Cache: {0})", Model.CacheDuration)
                                : string.Format("Render Macro: {0}, type: {1}, cache: {2})", Name, Model.MacroType, Model.CacheDuration);

            using (DisposableTimer.DebugDuration<macro>(macroInfo))
            {
                TraceInfo("renderMacro", macroInfo, excludeProfiling:true);

                StateHelper.SetContextValue(MacrosAddedKey, StateHelper.GetContextValue<int>(MacrosAddedKey) + 1);

                // zb-00037 #29875 : parse attributes here (and before anything else)
                foreach (MacroPropertyModel prop in Model.Properties)
                    prop.Value = helper.parseAttribute(pageElements, prop.Value);

                Model.CacheIdentifier = GetCacheIdentifier(Model, pageElements, pageId);

                string macroHtml;
                Control macroControl;
                //get the macro from cache if it is there
                GetMacroFromCache(out macroHtml, out macroControl);

                // FlorisRobbemont: Empty macroHtml (not null, but "") doesn't mean a re-render is necessary
                if (macroHtml == null && macroControl == null)
                {
                    var renderFailed = false;
                    var macroType = Model.MacroType != MacroTypes.Unknown
                                        ? (int) Model.MacroType
                                        : MacroType;

                    switch (macroType)
                    {
                        case (int) MacroTypes.PartialView:

                            //error handler for partial views, is an action because we need to re-use it twice below
                            Func<Exception, Control> handleError = e =>
                                {
                                    LogHelper.WarnWithException<macro>("Error loading Partial View (file: " + ScriptFile + ")", true, e);
                                    // Invoke any error handlers for this macro
                                    var macroErrorEventArgs =
                                        new MacroErrorEventArgs
                                            {
                                                Name = Model.Name,
                                                Alias = Model.Alias,
                                                ItemKey = Model.ScriptName,
                                                Exception = e,
                                                Behaviour = UmbracoSettings.MacroErrorBehaviour
                                            };
                                    return GetControlForErrorBehavior("Error loading Partial View script (file: " + ScriptFile + ")", macroErrorEventArgs);
                                };

                            using (DisposableTimer.DebugDuration<macro>("Executing Partial View: " + Model.TypeName))
                            {
                                TraceInfo("umbracoMacro", "Partial View added (" + Model.TypeName + ")", excludeProfiling:true);
                                try
                                {
                                    var result = LoadPartialViewMacro(Model);
                                    macroControl = new LiteralControl(result.Result);
                                    if (result.ResultException != null)
                                    {
                                        renderFailed = true;
                                        Exceptions.Add(result.ResultException);
                                        macroControl = handleError(result.ResultException);
                                        //if it is null, then we are supposed to throw the exception
                                        if (macroControl == null)
                                        {
                                            throw result.ResultException;
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    renderFailed = true;
                                    Exceptions.Add(e);
                                    macroControl = handleError(e);
                                    //if it is null, then we are supposed to throw the (original) exception
                                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                                    if (macroControl == null)
                                    {
                                        throw;
                                    }
                                }

                                break;
                            }
                        case (int) MacroTypes.UserControl:

                            using (DisposableTimer.DebugDuration<macro>("Executing UserControl: " + Model.TypeName))
                            {
                                try
                                {
                                    TraceInfo("umbracoMacro", "Usercontrol added (" + Model.TypeName + ")", excludeProfiling:true);

                                    // Add tilde for v4 defined macros
                                    if (string.IsNullOrEmpty(Model.TypeName) == false &&
                                        Model.TypeName.StartsWith("~") == false)
                                        Model.TypeName = "~/" + Model.TypeName;

                                    macroControl = loadUserControl(ScriptType, Model, pageElements);
                                    break;
                                }
                                catch (Exception e)
                                {
                                    renderFailed = true;
                                    Exceptions.Add(e);
                                    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,
                                        ItemKey = Model.TypeName,
                                        Exception = e,
                                        Behaviour = UmbracoSettings.MacroErrorBehaviour
                                    };

                                    macroControl = GetControlForErrorBehavior("Error loading userControl '" + Model.TypeName + "'", macroErrorEventArgs);
                                    //if it is null, then we are supposed to throw the (original) exception
                                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                                    if (macroControl == null)
                                    {
                                        throw;
                                    }

                                    break;
                                }
                            }
                            
                        case (int) MacroTypes.CustomControl:

                            using (DisposableTimer.DebugDuration<macro>("Executing CustomControl: " + Model.TypeName + "." + Model.TypeAssembly))
                            {
                                try
                                {
                                    TraceInfo("umbracoMacro", "Custom control added (" + Model.TypeName + "), ScriptAssembly: " + Model.TypeAssembly, excludeProfiling: true);
                                    macroControl = loadControl(Model.TypeAssembly, ScriptType, Model, pageElements);
                                    break;
                                }
                                catch (Exception e)
                                {
                                    renderFailed = true;
                                    Exceptions.Add(e);

                                    LogHelper.WarnWithException<macro>(
                                        "Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" +
                                        Model.TypeName + "'", true, e);

                                    // Invoke any error handlers for this macro
                                    var macroErrorEventArgs = new MacroErrorEventArgs
                                    {
                                        Name = Model.Name,
                                        Alias = Model.Alias,
                                        ItemKey = Model.TypeAssembly,
                                        Exception = e,
                                        Behaviour = UmbracoSettings.MacroErrorBehaviour
                                    };

                                    macroControl = GetControlForErrorBehavior("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", macroErrorEventArgs);
                                    //if it is null, then we are supposed to throw the (original) exception
                                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                                    if (macroControl == null)
                                    {
                                        throw;
                                    }

                                    break;
                                }
                            }
                        case (int) MacroTypes.XSLT:                            
                            macroControl = LoadMacroXslt(this, Model, pageElements, true);
                            break;                                                           
                        case (int) MacroTypes.Script:

                            //error handler for partial views, is an action because we need to re-use it twice below
                            Func<Exception, Control> handleMacroScriptError = e =>
                                {
                                    LogHelper.WarnWithException<macro>("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", true, e);

                                    // Invoke any error handlers for this macro
                                    var macroErrorEventArgs =
                                        new MacroErrorEventArgs
                                            {
                                                Name = Model.Name,
                                                Alias = Model.Alias,
                                                ItemKey = ScriptFile,
                                                Exception = e,
                                                Behaviour = UmbracoSettings.MacroErrorBehaviour
                                            };

                                    return GetControlForErrorBehavior("Error loading MacroEngine script (file: " + ScriptFile + ")", macroErrorEventArgs);
                                };

                            using (DisposableTimer.DebugDuration<macro>("Executing MacroEngineScript: " + ScriptFile))
                            {
                                try
                                {
                                    TraceInfo("umbracoMacro", "MacroEngine script added (" + ScriptFile + ")", excludeProfiling: true);
                                    ScriptingMacroResult result = loadMacroScript(Model);
                                    macroControl = new LiteralControl(result.Result);
                                    if (result.ResultException != null)
                                    {
                                        renderFailed = true;
                                        Exceptions.Add(result.ResultException);
                                        macroControl = handleMacroScriptError(result.ResultException);
                                        //if it is null, then we are supposed to throw the exception
                                        if (macroControl == null)
                                        {
                                            throw result.ResultException;
                                        }
                                    }
                                    break;
                                }
                                catch (Exception e)
                                {
                                    renderFailed = true;
                                    Exceptions.Add(e);

                                    macroControl = handleMacroScriptError(e);
                                    //if it is null, then we are supposed to throw the (original) exception
                                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                                    if (macroControl == null)
                                    {
                                        throw;
                                    }
                                    break;
                                }
                            }
                        case (int) MacroTypes.Unknown:
                        default:
                            if (GlobalSettings.DebugMode)
                            {
                                macroControl = new LiteralControl("&lt;Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + ")&gt;");
                            }
                            break;
                    }

                    //add to cache if render is successful
                    if (renderFailed == false)
                    {
                        macroControl = AddMacroResultToCache(macroControl);
                    }

                }
                else if (macroControl == null)
                {
                    macroControl = new LiteralControl(macroHtml);
                }

                return macroControl;
            }
        }
Exemple #4
0
 /// <summary>
 /// Raises the <see cref="MacroErrorEventArgs"/> event.
 /// </summary>
 /// <param name="e">The <see cref="MacroErrorEventArgs"/> instance containing the event data.</param>
 protected void OnError(MacroErrorEventArgs e)
 {
     if (Error != null)
     {
         Error(this, e);
     }
 }
 void macro_Error(object sender, MacroErrorEventArgs e)
 {
     // From http://stackoverflow.com/a/5936867/1110395:
     ErrorSignal.FromCurrentContext().Raise(e.Exception);
 }
Exemple #6
0
        internal Control LoadMacroXslt(macro macro, MacroModel model, Hashtable pageElements, bool throwError)
        {
            if (XsltFile.Trim() != string.Empty)
            {
                // Get main XML
                var umbracoXml = content.Instance.XmlContent;

                // Create XML document for Macro
                var macroXml = new XmlDocument();
                macroXml.LoadXml("<macro/>");

                foreach (var prop in macro.Model.Properties)
                {
                    addMacroXmlNode(umbracoXml, macroXml, prop.Key, prop.Type, prop.Value);
                }

                if (HttpContext.Current.Request.QueryString["umbDebug"] != null && GlobalSettings.DebugMode)
                {
                    return
                        new LiteralControl("<div style=\"border: 2px solid green; padding: 5px;\"><b>Debug from " +
                                           macro.Name +
                                           "</b><br/><p>" + HttpContext.Current.Server.HtmlEncode(macroXml.OuterXml) +
                                           "</p></div>");
                }

                try
                {
                    var xsltFile = getXslt(XsltFile);

                    try
                    {
                        var result = CreateControlsFromText(GetXsltTransformResult(macroXml, xsltFile));

                        TraceInfo("umbracoMacro", "After performing transformation");

                        return result;
                    }
                    catch (Exception e)
                    {
                        Exceptions.Add(e);
                        LogHelper.WarnWithException<macro>("Error parsing XSLT file", e);
                        // inner exception code by Daniel Lindstr?m from SBBS.se
                        Exception ie = e;
                        while (ie != null)
                        {
                            TraceWarn("umbracoMacro InnerException", ie.Message, ie);
                            ie = ie.InnerException;
                        }

                        var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                        var macroControl = GetControlForErrorBehavior("Error parsing XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs);
                        //if it is null, then we are supposed to throw the (original) exception
                        // see: http://issues.umbraco.org/issue/U4-497 at the end
                        if (macroControl == null && throwError)
                        {
                            throw;
                        }
                        return macroControl;
                    }
                }
                catch (Exception e)
                {
                    Exceptions.Add(e);
                    LogHelper.WarnWithException<macro>("Error loading XSLT " + Model.Xslt, true, e);

                    // Invoke any error handlers for this macro
                    var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.Xslt, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                    var macroControl = GetControlForErrorBehavior("Error reading XSLT file: \\xslt\\" + XsltFile, macroErrorEventArgs);
                    //if it is null, then we are supposed to throw the (original) exception
                    // see: http://issues.umbraco.org/issue/U4-497 at the end
                    if (macroControl == null && throwError)
                    {
                        throw;
                    }
                    return macroControl;
                }
            }

            TraceWarn("macro", "Xslt is empty");
            return new LiteralControl(string.Empty);
        }
Exemple #7
0
        public Control renderMacro(Hashtable pageElements, int pageId)
        {
	        TraceInfo("renderMacro",
	                  string.Format("Rendering started (macro: {0}, type: {1}, cacheRate: {2})",
	                                Name, MacroType, Model.CacheDuration));

            StateHelper.SetContextValue(macrosAddedKey, StateHelper.GetContextValue<int>(macrosAddedKey) + 1);

            String macroHtml = null;
            Control macroControl = null;

            // zb-00037 #29875 : parse attributes here (and before anything else)
            foreach (MacroPropertyModel prop in Model.Properties)
                prop.Value = helper.parseAttribute(pageElements, prop.Value);

            Model.CacheIdentifier = GetCacheIdentifier(Model, pageElements, pageId);

            if (!UmbracoContext.Current.InPreviewMode && Model.CacheDuration > 0)
            {
                if (cacheMacroAsString(Model))
                {
                    macroHtml = macroCache["macroHtml_" + Model.CacheIdentifier] as String;

                    // FlorisRobbemont: 
                    // An empty string means: macroHtml has been cached before, but didn't had any output (Macro doesn't need to be rendered again)
                    // An empty reference (null) means: macroHtml has NOT been cached before
                    if (macroHtml != null)
                    {
                        if (MacroNeedsToBeClearedFromCache(Model, "macroHtml_DateAdded_" + Model.CacheIdentifier))
                        {
                            macroHtml = null;
	                        TraceInfo("renderMacro",
	                                  string.Format("Macro removed from cache due to file change '{0}'.",
	                                                Model.CacheIdentifier));
                        }
                        else
                        {
	                        TraceInfo("renderMacro",
	                                  string.Format("Macro Content loaded from cache '{0}'.",
	                                                Model.CacheIdentifier));
                        }

                    }
                }
                else
                {
                    var cacheContent = macroCache["macroControl_" + Model.CacheIdentifier] as MacroCacheContent;

                    if (cacheContent != null)
                    {
                        macroControl = cacheContent.Content;
                        macroControl.ID = cacheContent.ID;

                        if (MacroNeedsToBeClearedFromCache(Model, "macroControl_DateAdded_" + Model.CacheIdentifier))
                        {
	                        TraceInfo("renderMacro",
	                                  string.Format("Macro removed from cache due to file change '{0}'.",
	                                                Model.CacheIdentifier));
                            macroControl = null;
                        }
                        else
                        {
	                        TraceInfo("renderMacro",
	                                  string.Format("Macro Control loaded from cache '{0}'.",
	                                                Model.CacheIdentifier));
                        }
    
                    }
                }
            }

            // FlorisRobbemont: Empty macroHtml (not null, but "") doesn't mean a re-render is necessary
            if (macroHtml == null && macroControl == null)
            {
                bool renderFailed = false;
                int macroType = Model.MacroType != MacroTypes.Unknown ? (int)Model.MacroType : MacroType;
                switch (macroType)
                {
					case (int)MacroTypes.PartialView:

                        //error handler for partial views, is an action because we need to re-use it twice below
                        Func<Exception, Control> handleError = e =>
                            {
                                LogHelper.WarnWithException<macro>("Error loading Partial View (file: " + ScriptFile + ")", true, e);
                                // Invoke any error handlers for this macro
                                var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = Model.ScriptName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };
                                return GetControlForErrorBehavior("Error loading Partial View script (file: " + ScriptFile + ")", macroErrorEventArgs);
                            };

						TraceInfo("umbracoMacro", "Partial View added (" + Model.TypeName + ")");
						try
						{							
							var result = LoadPartialViewMacro(Model);
							macroControl = new LiteralControl(result.Result);
							if (result.ResultException != null)
							{
								renderFailed = true;
                                Exceptions.Add(result.ResultException);
                                macroControl = handleError(result.ResultException);
                                //if it is null, then we are supposed to throw the exception
                                if (macroControl == null)
                                {
                                    throw result.ResultException;
                                }
							}
						}
						catch (Exception e)
						{
							renderFailed = true;
							Exceptions.Add(e);						    
						    macroControl = handleError(e);
                            //if it is null, then we are supposed to throw the (original) exception
                            // see: http://issues.umbraco.org/issue/U4-497 at the end
                            if (macroControl == null)
                            {
                                throw;
                            }
						}

		                break;
                    case (int)MacroTypes.UserControl:
                        try
                        {
							TraceInfo("umbracoMacro","Usercontrol added (" + Model.TypeName + ")");
                            
                            // Add tilde for v4 defined macros
                            if (string.IsNullOrEmpty(Model.TypeName) == false && Model.TypeName.StartsWith("~") == false)
                                Model.TypeName = "~/" + Model.TypeName;

                            macroControl = loadUserControl(ScriptType, Model, pageElements);
                            break;
                        }
                        catch (Exception e)
                        {
                            renderFailed = true;
                            Exceptions.Add(e);
							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, ItemKey = Model.TypeName, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour};

                            macroControl = GetControlForErrorBehavior("Error loading userControl '" + Model.TypeName + "'", macroErrorEventArgs);
                            //if it is null, then we are supposed to throw the (original) exception
                            // see: http://issues.umbraco.org/issue/U4-497 at the end
                            if (macroControl == null)
                            {
                                throw;
                            }

                            break;
                        }
                    case (int)MacroTypes.CustomControl:
                        try
                        {
	                        TraceInfo("umbracoMacro", "Custom control added (" + Model.TypeName + ")");
	                        TraceInfo("umbracoMacro", "ScriptAssembly (" + Model.TypeAssembly + ")");
                            macroControl = loadControl(Model.TypeAssembly, ScriptType, Model, pageElements);
                            break;
                        }
                        catch (Exception e)
                        {
                            renderFailed = true;
                            Exceptions.Add(e);

	                        LogHelper.WarnWithException<macro>("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", true, e);

                            // Invoke any error handlers for this macro
                            var macroErrorEventArgs = new MacroErrorEventArgs {Name = Model.Name, Alias = Model.Alias, ItemKey = Model.TypeAssembly, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour};

                            macroControl = GetControlForErrorBehavior("Error loading customControl (Assembly: " + Model.TypeAssembly + ", Type: '" + Model.TypeName + "'", macroErrorEventArgs);
                            //if it is null, then we are supposed to throw the (original) exception
                            // see: http://issues.umbraco.org/issue/U4-497 at the end
                            if (macroControl == null)
                            {
                                throw;
                            }

                            break;
                        }
                    case (int)MacroTypes.XSLT:
                        macroControl = LoadMacroXslt(this, Model, pageElements, true);
                        break;
                    case (int)MacroTypes.Script:

                        //error handler for partial views, is an action because we need to re-use it twice below
                        Func<Exception, Control> handleMacroScriptError = e =>
                        {
                            LogHelper.WarnWithException<macro>("Error loading MacroEngine script (file: " + ScriptFile + ", Type: '" + Model.TypeName + "'", true, e);

                            // Invoke any error handlers for this macro
                            var macroErrorEventArgs = new MacroErrorEventArgs { Name = Model.Name, Alias = Model.Alias, ItemKey = ScriptFile, Exception = e, Behaviour = UmbracoSettings.MacroErrorBehaviour };

                            return GetControlForErrorBehavior("Error loading MacroEngine script (file: " + ScriptFile + ")", macroErrorEventArgs);
                        };
                        
                        try
                        {
	                        TraceInfo("umbracoMacro", "MacroEngine script added (" + ScriptFile + ")");
                            ScriptingMacroResult result = loadMacroScript(Model);
                            macroControl = new LiteralControl(result.Result);
                            if (result.ResultException != null)
                            {
                                renderFailed = true;
                                Exceptions.Add(result.ResultException);
                                macroControl = handleMacroScriptError(result.ResultException);
                                //if it is null, then we are supposed to throw the exception
                                if (macroControl == null)
                                {
                                    throw result.ResultException;
                                }
                            }
                            break;
                        }
                        catch (Exception e)
                        {
                            renderFailed = true;
                            Exceptions.Add(e);

                            macroControl = handleMacroScriptError(e);
                            //if it is null, then we are supposed to throw the (original) exception
                            // see: http://issues.umbraco.org/issue/U4-497 at the end
                            if (macroControl == null)
                            {
                                throw;
                            }

                            break;
                        }
                    default:
                        if (GlobalSettings.DebugMode)
                            macroControl = new LiteralControl("&lt;Macro: " + Name + " (" + ScriptAssembly + "," + ScriptType + ")&gt;");
                        break;
                }

                // Add result to cache if successful
                if (!renderFailed && Model.CacheDuration > 0)
                {
                    // do not add to cache if there's no member and it should cache by personalization
                    if (!Model.CacheByMember || (Model.CacheByMember && Member.GetCurrentMember() != null))
                    {
                        if (macroControl != null)
                        {
                            // NH: Scripts and XSLT can be generated as strings, but not controls as page events wouldn't be hit (such as Page_Load, etc)
                            if (cacheMacroAsString(Model))
                            {
                                string outputCacheString = "";

                                using (var sw = new StringWriter())
                                {
                                    var hw = new HtmlTextWriter(sw);
                                    macroControl.RenderControl(hw);

                                    outputCacheString = sw.ToString();
                                }

                                macroCache.Insert("macroHtml_" + Model.CacheIdentifier,
                                                outputCacheString,

                                                null,
                                                DateTime.Now.AddSeconds(Model.CacheDuration),
                                                TimeSpan.Zero,
                                                CacheItemPriority.NotRemovable, //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable

                                                null);



                                                macroCache.Insert("macroHtml_DateAdded_" + Model.CacheIdentifier,
                                                DateTime.Now,

                                                null,
                                                DateTime.Now.AddSeconds(Model.CacheDuration),
                                                TimeSpan.Zero,
                                                CacheItemPriority.NotRemovable, //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable

                                                null);

                                // zb-00003 #29470 : replace by text if not already text
                                // otherwise it is rendered twice
                                if (!(macroControl is LiteralControl))
                                    macroControl = new LiteralControl(outputCacheString);

	                            TraceInfo("renderMacro",
	                                      string.Format("Macro Content saved to cache '{0}'.", Model.CacheIdentifier));

                            }

                            else
                            {
                                macroCache.Insert("macroControl_" + Model.CacheIdentifier,
                                                new MacroCacheContent(macroControl, macroControl.ID), null,
                                                DateTime.Now.AddSeconds(Model.CacheDuration), TimeSpan.Zero,
                                                CacheItemPriority.NotRemovable, //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable

                                                null);


                                macroCache.Insert("macroControl_DateAdded_" + Model.CacheIdentifier,
                                                 DateTime.Now, null,
                                                 DateTime.Now.AddSeconds(Model.CacheDuration), TimeSpan.Zero,
                                                 CacheItemPriority.NotRemovable, //FlorisRobbemont: issue #27610 -> Macro output cache should not be removable

                                                 null);

	                            TraceInfo("renderMacro",
	                                      string.Format("Macro Control saved to cache '{0}'.", Model.CacheIdentifier));
                            }
                        }
                    }
                }
            }
            else if (macroControl == null)
            {
                // FlorisRobbemont: Extra check to see if the macroHtml is not null
                macroControl = new LiteralControl(macroHtml == null ? "" : macroHtml);
            }

            return macroControl;
        }