Exemplo n.º 1
0
        /// <summary>
        /// Renders the main contents of the page.
        /// </summary>
        /// <param name="sb">The <see cref="StringBuilder"/> to render to.</param>
        protected override void RenderInnerHtml(StringBuilder sb)
        {
            void RenderVariableTable(string title, string className, NameValueCollection vars)
            {
                if (vars == null || vars.Count == 0)
                {
                    return;
                }

                var fetchError = vars[Constants.CollectionErrorKey];
                var errored    = fetchError.HasValue();
                var keys       = vars.AllKeys.Where(key => !HiddenHttpKeys.Contains(key) && key != Constants.CollectionErrorKey).OrderBy(k => k);

                sb.AppendFormat("  <div class=\"{0}\">", className).AppendLine();
                if (errored)
                {
                    sb.AppendFormat("    <h3 class=\"title-error\">{0} - Error while gathering data</h3>", title).AppendLine();
                }
                else
                {
                    sb.AppendFormat("    <h3>{0}</h3>", title).AppendLine();
                }
                if (keys.Any())
                {
                    var hiddenRows = new StringBuilder();
                    sb.AppendLine("    <div class=\"side-scroll\">")
                    .AppendLine("      <table class=\"alt-rows key-value\">")
                    .AppendLine("        <tbody>");
                    foreach (var k in keys)
                    {
                        // If this has no value, skip it
                        if (vars[k].HasValue())
                        {
                            // If this is a hidden row, buffer it up, since CSS has no clean mechanism for :visible:nth-row(odd) type styling behavior
                            (DefaultHttpKeys.Contains(k) ? hiddenRows : sb).AppendFormat("        <tr><td>{0}</td><td>{1}</td></tr>", k, Linkify(vars[k])).AppendLine();
                        }
                    }
                    if (vars["HTTP_HOST"].HasValue() && vars["URL"].HasValue())
                    {
                        var ssl = vars["HTTP_X_FORWARDED_PROTO"] == "https" || vars["HTTP_X_SSL"].HasValue() || vars["HTTPS"] == "on";
                        var url = string.Format("http{3}://{0}{1}{2}", vars["HTTP_HOST"], vars["URL"], vars["QUERY_STRING"].HasValue() ? "?" + vars["QUERY_STRING"] : "", ssl ? "s" : "");
                        sb.AppendFormat("        <tr><td>URL and Query</td><td>{0}</td></tr>", vars["REQUEST_METHOD"] == "GET" ? Linkify(url) : url.HtmlEncode()).AppendLine();
                    }
                    sb.AppendLine("        </tbody>");
                    if (hiddenRows.Length > 0)
                    {
                        sb.AppendLine("        <tbody class=\"hidden\">")
                        .Append(hiddenRows)
                        .AppendLine("        </tbody>");
                    }
                    sb.AppendLine("      </table>")
                    .AppendLine("    </div>");
                }
                if (errored)
                {
                    sb.AppendFormat("<span class=\"custom-error-label\">Get {0} threw an exception:</span>", title)
                    .AppendFormat("<pre class=\"stack\"><code>{0}</code></pre>", fetchError.HtmlEncode());
                }
                sb.AppendFormat("  </div>");
            }

            void RenderKeyValueTable(IEnumerable <KeyValuePair <string, string> > kvPairs)
            {
                if (kvPairs?.Any() == true)
                {
                    sb.AppendLine("    <div class=\"side-scroll\">")
                    .AppendLine("      <table class=\"alt-rows key-value\">");
                    foreach (var kv in kvPairs)
                    {
                        sb.Append("        <tr>")
                        .Append("<td>").AppendHtmlEncode(kv.Key).Append("</td>")
                        .Append("<td>").Append(Linkify(kv.Value)).Append("</td>")
                        .AppendLine("</tr>");
                    }
                    sb.AppendLine("      </table>")
                    .AppendLine("    </div>");
                }
            }

            if (Error == null)
            {
                sb.AppendFormat("  <h1 class=\"not-found\">Oh no! Error {0} was not found!</h1>", _guid.ToString()).AppendLine();
            }
            else
            {
                sb.Append("  <h1>").AppendHtmlEncode(Error.Message).AppendLine("</h1>")
                .Append("  <div class=\"subtitle\">").AppendHtmlEncode(Error.Type);
                if (Error.DuplicateCount > 1)
                {
                    sb.Append(" <span class=\"duplicate-count\">(thrown ").Append(Error.DuplicateCount.Value).AppendLine(" times)</span>");
                }
                sb.AppendLine("</div>")
                .Append("  <pre class=\"stack dark\"><code class=\"nohighlight\">").Append(Utils.StackTrace.HtmlPrettify(Error.Detail)).AppendLine().AppendLine("</code></pre>")
                // TODO: Controls for show/hide of async .stack.row.async in the block above
                // TODO: Remove - temporarily showing the raw while the user-friendlier display above gets tuned
                //.Append("  <pre class=\"stack\"><code>").AppendHtmlEncode(Error.Detail).AppendLine().AppendLine("</code></pre>")
                .Append("  <p class=\"sub-info\">occurred <b title=\"")
                .AppendHtmlEncode(Error.CreationDate.ToLongDateString()).Append(" at ").AppendHtmlEncode(Error.CreationDate.ToLongTimeString())
                .Append("\">")
                .Append(Error.CreationDate.ToRelativeTime())
                .Append("</b> on ")
                .AppendHtmlEncode(Error.MachineName);
                if (ShowActionLinks)
                {
                    sb.Append(" <span>(<a href=\"delete?guid=").Append(Error.GUID.ToString()).AppendLine("\">delete</a>)</span>");
                }
                sb.Append("</p>");
                if (Error.Commands != null)
                {
                    foreach (var cmd in Error.Commands)
                    {
                        var lang = cmd.GetHighlightLanguage();
                        sb.Append("  <h3>Command: ").AppendHtmlEncode(cmd.Type).AppendLine("</h3>")
                        .Append("  <pre class=\"command\"><code");
                        if (lang.HasValue())
                        {
                            sb.Append(" class=\"").Append(lang).Append("\"");
                        }
                        sb.Append(">")
                        .AppendHtmlEncode(cmd.CommandString)
                        .AppendLine("</code></pre>");

                        RenderKeyValueTable(cmd.Data);
                    }
                }
                RenderVariableTable("Server Variables", "server-variables", Error.ServerVariables);

                if (Error.CustomData?.Count > 0)
                {
                    var errored = Error.CustomData.ContainsKey(Constants.CustomDataErrorKey);
                    var cdKVs   = Error.CustomData.Where(kv => kv.Key != Constants.CustomDataErrorKey);
                    sb.AppendLine("  <div class=\"custom-data\">");
                    if (errored)
                    {
                        sb.AppendLine("    <h3 class=\"title-error\">Custom - Error while gathering custom data</h3>");
                    }
                    else
                    {
                        sb.AppendLine("    <h3>Custom</h3>");
                    }
                    if (cdKVs.Any())
                    {
                        RenderKeyValueTable(cdKVs);
                    }
                    if (errored)
                    {
                        sb.AppendLine("    <span class=\"custom-error-label\">GetCustomData threw an exception:</span>")
                        .AppendLine("    <pre class=\"stack\"><code>").Append(Error.CustomData[Constants.CustomDataErrorKey]).AppendLine("</code></pre>");
                    }
                    sb.AppendLine("  </div>");
                }
                RenderVariableTable("Querystring", "querystring", Error.QueryString);
                RenderVariableTable("Form", "form", Error.Form);
                RenderVariableTable("Cookies", "cookies", Error.Cookies);
                RenderVariableTable("Request Headers", "headers", Error.RequestHeaders);
            }
        }
Exemplo n.º 2
0
        protected override void RenderHtml(StringBuilder sb)
        {
            void RenderVariableTable(string title, NameValueCollection vars, bool renderUrls = false)
            {
                if (vars == null || vars.Count == 0)
                {
                    return;
                }

                var fetchError = vars[Constants.CollectionErrorKey];
                var errored    = fetchError.HasValue();
                var keys       = vars.AllKeys.Where(key => !HiddenHttpKeys.Contains(key) && key != Constants.CollectionErrorKey).OrderBy(k => k);

                sb.AppendFormat("  <div>").AppendLine();
                sb.AppendFormat("    <h3 style=\"color: #224C00; font-family: Verdana, Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 14px; margin: 10px 0 5px 0;\">{0}{1}</h3>", title, errored ? " - Error while gathering data" : "").AppendLine();
                if (keys.Any())
                {
                    sb.AppendFormat("    <table style=\"font-family: Verdana, Tahoma, Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; width: 100%; border-collapse: collapse; border: 0;\">").AppendLine();
                    var i = 0;
                    string getBackground() => i++ % 2 == 1 ? " style=\"background-color: #F2F2F2;\"" : "";

                    foreach (var k in keys)
                    {
                        // If this has no value, skip it
                        if (vars[k].IsNullOrEmpty() || DefaultHttpKeys.Contains(k))
                        {
                            continue;
                        }
                        sb.AppendFormat("      <tr{2}><td style=\"padding: 0.4em; width: 200px;\">{0}</td><td style=\"padding: 0.4em;\">{1}</td></tr>", k, Linkify(vars[k]), getBackground()).AppendLine();
                    }
                    if (renderUrls && vars["Request Method"].IsNullOrEmpty()) // told to render and we don't have them elsewhere
                    {
                        var method = error.HTTPMethod;
                        if (method.HasValue())
                        {
                            sb.AppendFormat("        <tr{1}><td style=\"padding: 0.4em; width: 200px;\">Method</td><td style=\"padding: 0.4em;\">{0}</td></tr>", method, getBackground()).AppendLine();
                            var fullUrl = error.GetFullUrl();
                            if (fullUrl.HasValue())
                            {
                                sb.AppendFormat("      <tr{1}><td style=\"padding: 0.4em; width: 200px;\">URL and Query</td><td style=\"padding: 0.4em;\">{0}</td></tr>", method == "GET" ? Linkify(fullUrl) : fullUrl.HtmlEncode(), getBackground()).AppendLine();
                            }
                        }
                    }
                    sb.AppendFormat("    </table>").AppendLine();
                }
                if (errored)
                {
                    sb.AppendFormat("    <span style=\"color: maroon;\">Get {0} threw an exception:</span>", title).AppendLine();
                    sb.AppendFormat("    <pre  style=\"background-color: #EEE; font-family: Consolas, Monaco, monospace; padding: 8px;\">{0}</pre>", fetchError.HtmlEncode()).AppendLine();
                }
                sb.AppendFormat("  </div>").AppendLine();
            }

            sb.AppendLine("<div style=\"font-family: Arial, \'Helvetica Neue\', Helvetica, sans-serif;\">");

            if (error == null)
            {
                sb.AppendLine("  <h1 style=\"color: maroon; font-size: 16px;\">Error not found.</h1>");
            }
            else
            {
                sb.Append("  <h1 style=\"color: maroon; font-size: 16px; padding: 0; margin: 0;\">")
                .AppendHtmlEncode(error.Message)
                .Append("</h1>").AppendLine()
                .Append("  <div style=\"font-size: 12px; color: #444; padding: 0; margin: 2px 0;\">")
                .AppendHtmlEncode(error.Type)
                .Append("</div>").AppendLine()
                .Append("  <pre style=\"background-color: #FFFFCC; font-family: Consolas, Monaco, monospace; font-size: 12px; margin: 2px 0; padding: 12px;\">")
                .AppendHtmlEncode(error.Detail).AppendLine()
                .Append("  </pre>").AppendLine()
                .Append("  <p class=\"error-time\" style=\"font-size: 13px; color: #555; margin: 5px 0;\">occurred at <b title=\"")
                .AppendHtmlEncode(error.CreationDate.ToLongDateString())
                .Append(" at ")
                .AppendHtmlEncode(error.CreationDate.ToLongTimeString())
                .Append("\">")
                .AppendHtmlEncode(error.CreationDate.ToUniversalTime().ToString())
                .Append(" UTC</b> on ")
                .AppendHtmlEncode(error.MachineName)
                .Append("</p>")
                .AppendLine();

                // TODO: Commands
                //if (!string.IsNullOrEmpty(error.SQL))
                //{
                //    sb.Append("  <h3 style=\"color: #224C00; font-family: Verdana, Tahoma, Arial, \'Helvetica Neue\', Helvetica, sans-serif; font-size: 14px; margin: 10px 0 5px 0;\">SQL</h3>")
                //      .AppendLine()
                //      .Append("  <pre style=\"background-color: #EEE; font-family: Consolas, Monaco, monospace; padding: 8px 8px 8px 8px; margin: 2px 0;\">")
                //      .AppendHtmlEncode(error.SQL)
                //      .Append("</pre>").AppendLine()
                //      .Append("<br/>").AppendLine();
                //}

                RenderVariableTable("Server Variables", error.ServerVariables, renderUrls: true);

                if (error.CustomData?.Count > 0)
                {
                    var errored = error.CustomData.ContainsKey(Constants.CustomDataErrorKey);
                    var cdKeys  = error.CustomData.Keys.Where(k => k != Constants.CustomDataErrorKey);
                    sb.AppendLine("  <div class=\"custom-data\">");
                    if (errored)
                    {
                        sb.AppendLine("    <h3 style=\"color: maroon; font-family: Verdana, Tahoma, Arial, \'Helvetica Neue\', Helvetica, sans-serif; font-size: 14px; margin: 10px 0 5px 0;\">Custom - Error while gathering custom data</h3>");
                    }
                    else
                    {
                        sb.AppendLine("    <h3 style=\"color: #224C00; font-family: Verdana, Tahoma, Arial, \'Helvetica Neue\', Helvetica, sans-serif; font-size: 14px; margin: 10px 0 5px 0;\">Custom</h3>\r\n");
                    }

                    if (cdKeys.Any(k => k != Constants.CustomDataErrorKey))
                    {
                        var i = -1;
                        sb.AppendLine("     <table style=\"font-family: Verdana, Tahoma, Arial, \'Helvetica Neue\', Helvetica, sans-serif; font-size: 12px; width: 100%; border-collapse: collapse; border: 0;\">\r\n");

                        foreach (var cd in cdKeys)
                        {
                            i++;
                            sb.Append("      <tr");
                            if (i % 2 == 0)
                            {
                                sb.Append(" style=\"background-color: #F2F2F2;\"");
                            }
                            sb.AppendLine(">")
                            .AppendLine("        <td style=\"padding: 0.4em; width: 200px;\">")
                            .AppendHtmlEncode(cd)
                            .AppendLine("</td>")
                            .Append("        <td style=\"padding: 0.4em;\">")
                            .Append(Linkify(error.CustomData[cd]))
                            .AppendLine("</td>")
                            .AppendLine("      </tr>");
                        }
                        sb.AppendLine("    </table>");
                    }

                    if (errored)
                    {
                        sb.AppendLine("    <span style=\"color: maroon;\">GetCustomData threw an exception:</span>")
                        .Append("    <pre style=\"background-color: #EEE; font-family: Consolas, Monaco, monospace; padding: 8px;\">")
                        .AppendHtmlEncode(error.CustomData[Constants.CustomDataErrorKey])
                        .AppendLine("</pre>");
                    }
                    sb.AppendLine("  </div>");
                }
                RenderVariableTable("QueryString", error.QueryString);
                RenderVariableTable("Form", error.Form);
                RenderVariableTable("Cookies", error.Cookies);
            }
            sb.AppendLine("</div>");
        }