Skip to content

Commit

Permalink
Reworked how stack traces are rendered
Browse files Browse the repository at this point in the history
  • Loading branch information
niemyjski committed Oct 4, 2023
1 parent cee7488 commit ceb09fa
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 317 deletions.
20 changes: 0 additions & 20 deletions src/Exceptionless.Web/ClientApp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions src/Exceptionless.Web/ClientApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@
"@exceptionless/browser": "^3.0.4",
"@iconify-json/mdi": "^1.1.54",
"@tanstack/svelte-table": "^8.10.3",
"@types/dompurify": "^3.0.3",
"@web3-storage/parse-link-header": "^3.1.0",
"class-validator": "^0.14.0",
"daisyui": "^3.8.3",
"dompurify": "^3.0.6",
"oidc-client-ts": "^2.3.0",
"svelte-local-storage-store": "^0.6.3",
"svelte-time": "^0.8.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,112 +1,30 @@
<script lang="ts">
import type { SimpleErrorInfo } from '$lib/models/client-data';
export let error: SimpleErrorInfo | undefined;
import { onMount } from 'svelte';
import { getErrors } from '$lib/helpers/persistent-event';
import DOMPurify from 'dompurify';
let textStackTrace: string;
let stackTrace: string;
function buildStackFrames(errors: SimpleErrorInfo[], includeHTML: boolean) {
let frames = '';
errors.forEach((error, index) => {
const stackTrace = error.stack_trace;
if (stackTrace) {
if (includeHTML) {
frames += `<div class="pl-[10px]">${escapeHTML(stackTrace.replace(' ', ''))}`;
if (index < errors.length - 1) {
frames += '<div>--- End of inner error stack trace ---</div>';
}
frames += '</div>';
} else {
frames += stackTrace.replace(' ', '');
if (index < errors.length - 1) {
frames += '--- End of inner error stack trace ---';
}
}
}
});
return frames;
}
import StackTraceHeader from './StackTraceHeader.svelte';
function buildStackTrace(errors: SimpleErrorInfo[], includeHTML: boolean) {
return (
buildStackTraceHeader(errors, includeHTML) +
buildStackFrames(errors.reverse(), includeHTML)
);
}
function buildStackTraceHeader(errors: SimpleErrorInfo[], includeHTML: boolean) {
let header = '';
errors.forEach((error, index) => {
if (includeHTML) {
header += '<span class="block">';
}
if (index > 0) {
header += ' ---> ';
}
const hasType = !!error.type;
if (hasType) {
if (includeHTML) {
header += `<span class="font-bold">${escapeHTML(error.type)}</span>: `;
} else {
header += `${error.type}: `;
}
}
if (error.message) {
if (includeHTML) {
header += escapeHTML(error.message);
} else {
header += error.message;
}
}
if (hasType) {
if (includeHTML) {
header += '</span>';
} else {
header += '\r\n';
}
}
});
return header;
}
function escapeHTML(input?: string) {
if (!input) {
return input;
}
export let error: SimpleErrorInfo | undefined;
return DOMPurify.sanitize(
input
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;')
);
function cleanStackTrace(stackTrace: string) {
return stackTrace.replace(' ', '');
}
onMount(() => {
const errors = getErrors(error);
stackTrace = buildStackTrace(errors, true);
textStackTrace = buildStackTrace(errors, false);
console.log({ stackTrace, textStackTrace });
});
const errors = getErrors(error);
</script>

<pre
class="max-h-[500px] overflow-y-scroll overflow-x-scroll break-normal resize-y whitespace-pre tab-size-2"><code
>{@html stackTrace}</code
></pre>
class="max-h-[500px] overflow-y-scroll overflow-x-scroll break-normal resize-y whitespace-pre tab-size-2">
<code>
<StackTraceHeader {errors}></StackTraceHeader>
{#each errors.reverse() as error, index}
{#if error.stack_trace}
<div class="pl-[10px]">{cleanStackTrace(
error.stack_trace
)}</div>
{#if index < errors.length - 1}
<div>--- End of inner error stack trace ---</div>
{/if}
{/if}
{/each}
</code>
</pre>
Loading

0 comments on commit ceb09fa

Please sign in to comment.