Skip to content

Commit 776f846

Browse files
committed
[#19] Add error handling in InferPage
1 parent ee74e72 commit 776f846

File tree

2 files changed

+105
-29
lines changed

2 files changed

+105
-29
lines changed

src/MaIN.InferPage/Components/Pages/Home.razor

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@
1313

1414
<PageTitle>MaIN Infer</PageTitle>
1515

16+
<div class="error-notification-wrapper">
17+
@if (!string.IsNullOrEmpty(_errorMessage))
18+
{
19+
<div class="error-shake">
20+
<FluentMessageBar @key="_errorMessage"
21+
Intent="@MessageIntent.Error"
22+
AllowDismiss="true"
23+
Multiline="true"
24+
OnDismiss="@(() => _errorMessage = null)"
25+
Class="high-alert-error">
26+
<Title>Error</Title>
27+
@_errorMessage
28+
</FluentMessageBar>
29+
</div>
30+
}
31+
</div>
32+
1633
<FluentGrid>
1734
<FluentGridItem sm="1" xs="1" lg="1"></FluentGridItem>
1835
<FluentGridItem sm="10" xs="10" lg="10" Style="align-self: center; align-items: center">
@@ -183,6 +200,7 @@
183200
private bool _isLoading;
184201
private bool _isThinking;
185202
private bool _reasoning;
203+
private string? _errorMessage;
186204
private string? _incomingMessage = null;
187205
private string? _incomingReasoning = null;
188206
private readonly string? _displayName = Utils.Model;
@@ -249,44 +267,61 @@
249267
_prompt = string.Empty;
250268
StateHasChanged();
251269
bool wasAtBottom = await JS.InvokeAsync<bool>("scrollManager.isAtBottom", "messages-container");
252-
await ctx!.WithMessage(msg)
253-
.CompleteAsync(changeOfValue: async message =>
254-
{
255-
if (message?.Type == TokenType.Reason)
256-
{
257-
_isThinking = true;
258-
_incomingReasoning += message.Text;
259-
}
260-
else if (message?.Type == TokenType.Message)
261-
{
262-
_isThinking = false;
263-
_incomingMessage += message.Text;
264-
}
265270

266-
StateHasChanged();
267-
if (wasAtBottom)
271+
try
272+
{
273+
await ctx!.WithMessage(msg)
274+
.CompleteAsync(changeOfValue: async message =>
268275
{
269-
await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", _bottomElement);
270-
}
271-
});
276+
if (message?.Type == TokenType.Reason)
277+
{
278+
_isThinking = true;
279+
_incomingReasoning += message.Text;
280+
}
281+
else if (message?.Type == TokenType.Message)
282+
{
283+
_isThinking = false;
284+
_incomingMessage += message.Text;
285+
}
286+
287+
StateHasChanged();
288+
if (wasAtBottom)
289+
{
290+
await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", _bottomElement);
291+
}
292+
});
293+
294+
_isLoading = false;
295+
var currentChat = (await ctx.GetCurrentChat());
296+
Chat.Messages.Add(currentChat.Messages.Last());
297+
Messages = Chat.Messages.Select(x => new MessageExt()
298+
{
299+
Message = x
300+
}).ToList();
301+
_incomingReasoning = null;
302+
_incomingMessage = null;
303+
await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", _bottomElement);
304+
StateHasChanged();
272305

273-
_isLoading = false;
274-
var currentChat = (await ctx.GetCurrentChat());
275-
Chat.Messages.Add(currentChat.Messages.Last());
276-
Messages = Chat.Messages.Select(x => new MessageExt()
306+
}
307+
catch (Exception ex)
277308
{
278-
Message = x
279-
}).ToList();
280-
_incomingReasoning = null;
281-
_incomingMessage = null;
282-
await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", _bottomElement);
283-
StateHasChanged();
309+
_errorMessage = null;
310+
StateHasChanged();
311+
312+
_errorMessage = $"{ex.Message}";
313+
}
314+
finally
315+
{
316+
_isLoading = false;
317+
_isThinking = false;
318+
StateHasChanged();
319+
}
284320
}
285321
}
286322

287323
private void Callback(ChangeEventArgs obj)
288324
{
289325
_prompt = obj.Value?.ToString()!;
290326
}
291-
292327
}

src/MaIN.InferPage/wwwroot/home.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,45 @@
5757

5858
.message-card p {
5959
margin: 0;
60+
}
61+
62+
.error-notification-wrapper {
63+
position: fixed;
64+
top: 30px;
65+
right: 30px;
66+
z-index: 9999;
67+
width: 550px;
68+
filter: drop-shadow(0 10px 15px rgba(0, 0, 0, 0.2));
69+
pointer-events: none;
70+
}
71+
72+
.error-notification-wrapper > div {
73+
pointer-events: auto;
74+
}
75+
76+
.high-alert-error {
77+
background-color: #d32f2f !important;
78+
color: #ffffff !important;
79+
border: none !important;
80+
font-size: 1.1rem !important;
81+
}
82+
83+
.high-alert-error * {
84+
color: #ffffff !important;
85+
fill: #ffffff !important;
86+
}
87+
88+
.high-alert-error .content {
89+
padding: 16px !important;
90+
}
91+
92+
.error-shake {
93+
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
94+
}
95+
96+
@keyframes shake {
97+
10%, 90% { transform: translate3d(-1px, 0, 0); }
98+
20%, 80% { transform: translate3d(2px, 0, 0); }
99+
30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
100+
40%, 60% { transform: translate3d(4px, 0, 0); }
60101
}

0 commit comments

Comments
 (0)