Skip to content

Commit af7441d

Browse files
committed
next: stack trace highlighting!
1 parent de46582 commit af7441d

24 files changed

+717
-194
lines changed

src/Exceptionless.Web/ClientApp/src/lib/features/events/components/simple-stack-trace.svelte

Lines changed: 0 additions & 26 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { SimpleErrorInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
error: SimpleErrorInfo;
6+
}
7+
8+
let { error }: Props = $props();
9+
</script>
10+
11+
{#if error.stack_trace}<div class="bg-inherit pl-[10px]">{error.stack_trace}</div>{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import type { SimpleErrorInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
error: SimpleErrorInfo;
6+
}
7+
8+
let { error }: Props = $props();
9+
</script>
10+
11+
<div class="bg-inherit">
12+
{#if error.type}<span class="mr-1 font-bold text-purple-400">{error.type}:</span>{/if}{#if error.message}{error.message}{/if}
13+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script module lang="ts">
2+
import { defineMeta } from '@storybook/addon-svelte-csf';
3+
4+
import type { SimpleErrorInfo } from '../../models/event-data';
5+
6+
import SimpleStackTrace from './simple-stack-trace.svelte';
7+
8+
const { Story } = defineMeta({
9+
component: SimpleStackTrace,
10+
tags: ['autodocs'],
11+
title: 'Components/Events/SimpleStackTrace'
12+
});
13+
14+
const error: SimpleErrorInfo = {
15+
message: 'Unhandled Exception: ea853120-8b1c-45f9-ba05-4f02dd965269',
16+
stack_trace:
17+
' at Dictionary<string, string> Acme.SampleAspNetCore.Controllers.ValuesController.Get() in /Acme.SampleAspNetCore/Controllers/ValuesController.cs:line 44\n at object lambda_method56(Closure, object, object[])\n at ValueTask<IActionResult> Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+SyncObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()+Logged(?)\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()+Awaited(?)\n at void Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\n at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)\n at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()+Awaited(?)\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeAsync()+Logged(?) x 2\n at async Task Acme.AspNetCore.AcmeMiddleware.Invoke(HttpContext context) in /Acme.AspNetCore/AcmeMiddleware.cs:line 24',
18+
type: 'Exception'
19+
};
20+
21+
const nestedErrors: SimpleErrorInfo = {
22+
inner: {
23+
message: 'Generated exception message.',
24+
stack_trace:
25+
' at Dictionary<string, string> Acme.SampleAspNetCore.Controllers.ValuesController.Get() in /Acme.SampleAspNetCore/Controllers/ValuesController.cs:line 44',
26+
type: 'System.NullReferenceException'
27+
},
28+
message: 'Generated exception message.',
29+
stack_trace:
30+
' at Dictionary<string, string> Acme.SampleAspNetCore.Controllers.ValuesController.Get() in /Acme.SampleAspNetCore/Controllers/ValuesController.cs:line 44\n at object lambda_method56(Closure, object, object[])\n at ValueTask<IActionResult> Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+SyncObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()+Logged(?)\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()+Awaited(?)\n at void Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\n at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)\n at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()+Awaited(?)\n at async Task Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeAsync()+Logged(?) x 2\n at async Task Acme.AspNetCore.AcmeMiddleware.Invoke(HttpContext context) in /Acme.AspNetCore/AcmeMiddleware.cs:line 24',
31+
type: 'System.AggregateException'
32+
};
33+
</script>
34+
35+
<Story name="Default" args={{ error: error }} />
36+
<Story name="Nested Errors" args={{ error: nestedErrors }} />
37+
<Story name="Empty" args={{ error: undefined }} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script lang="ts">
2+
import type { SimpleErrorInfo } from '$features/events/models/event-data';
3+
4+
import { Code } from '$comp/typography';
5+
import { getErrors } from '$features/events/persistent-event';
6+
7+
import SimpleStackTraceFrames from './simple-stack-trace-frames.svelte';
8+
import SimpleStackTraceHeader from './simple-stack-trace-header.svelte';
9+
10+
interface Props {
11+
error: SimpleErrorInfo;
12+
}
13+
14+
let { error }: Props = $props();
15+
16+
const errors = getErrors(error);
17+
</script>
18+
19+
<pre class="bg-muted rounded p-2 break-words whitespace-pre-wrap"><Code class="px-0"
20+
>{#each errors.reverse() as error, index}<SimpleStackTraceHeader {error} /><SimpleStackTraceFrames {error} />{#if index < errors.length - 1}<br
21+
/>{/if}{/each}</Code
22+
></pre>

src/Exceptionless.Web/ClientApp/src/lib/features/events/components/stack-trace-header.svelte

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/Exceptionless.Web/ClientApp/src/lib/features/events/components/stack-trace.stories.svelte

Lines changed: 0 additions & 127 deletions
This file was deleted.

src/Exceptionless.Web/ClientApp/src/lib/features/events/components/stack-trace.svelte

Lines changed: 0 additions & 22 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts">
2+
import type { StackFrameInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
frame: StackFrameInfo;
6+
}
7+
8+
let { frame }: Props = $props();
9+
</script>
10+
11+
{#if frame.file_name}{' '}in
12+
<span class="text-blue-400"
13+
>{frame.file_name}{#if frame.line_number}:line {frame.line_number}{/if}</span
14+
>{#if frame.column}:col <span class="text-blue-400">{frame.column}</span>{/if}{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { StackFrameInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
frame: StackFrameInfo;
6+
}
7+
8+
let { frame }: Props = $props();
9+
</script>
10+
11+
{#if frame.generic_arguments?.length}{'<'}<span class="text-purple-400">{frame.generic_arguments.join(', ')}</span>{'>'}{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { StackFrameInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
frame: StackFrameInfo;
6+
}
7+
8+
let { frame }: Props = $props();
9+
</script>
10+
11+
<span class="text-emerald-400">{frame.name || '<anonymous>'}</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import type { StackFrameInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
frame: StackFrameInfo;
6+
}
7+
8+
let { frame }: Props = $props();
9+
</script>
10+
11+
{#if frame.declaring_namespace || frame.declaring_type}<span class="text-purple-400"
12+
>{#if frame.declaring_namespace}{frame.declaring_namespace}.{/if}{#if frame.declaring_type}{frame.declaring_type.replace('+', '')}.{/if}</span
13+
>{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { StackFrameInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
frame: StackFrameInfo;
6+
}
7+
8+
let { frame }: Props = $props();
9+
</script>
10+
11+
{#if frame.data?.ILOffset || frame.data?.NativeOffset}{' '}at offset <span class="text-blue-400">{frame.data.ILOffset || frame.data.NativeOffset}</span>{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { ParameterInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
parameter: ParameterInfo;
6+
}
7+
8+
let { parameter }: Props = $props();
9+
</script>
10+
11+
{#if parameter.generic_arguments?.length}{'<'}<span class="text-purple-400">{parameter.generic_arguments.join(', ')}</span>{'>'}{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { ParameterInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
parameter: ParameterInfo;
6+
}
7+
8+
let { parameter }: Props = $props();
9+
</script>
10+
11+
{#if parameter.name}{' '}{parameter.name}{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import type { ParameterInfo } from '$features/events/models/event-data';
3+
4+
interface Props {
5+
parameter: ParameterInfo;
6+
}
7+
8+
let { parameter }: Props = $props();
9+
</script>
10+
11+
{#if parameter.type_namespace}<span class="text-purple-400">{parameter.type_namespace}.</span>{/if}{#if parameter.type}<span class="text-purple-400"
12+
>{parameter.type.replace('+', '')}</span
13+
>{/if}

0 commit comments

Comments
 (0)