Skip to content

Commit efb190c

Browse files
author
Alex J Lennon
committed
🔧 Add robust error handling for Monaco Editor
- Added error handling and fallback for Monaco Editor loading failures - Added fallback textarea when Monaco Editor fails to initialize - Added console error logging for debugging CDN issues - Improved CodeEditor component resilience - Added error recovery messaging for users This should resolve the 'unhandled error' issue on the deployed site and provide better user experience when Monaco Editor CDN is unavailable.
1 parent a5b9351 commit efb190c

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

src/web-tutorial/CSharpTutorial/Components/CodeEditor.razor

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
</div>
2121
<div class="card-body p-0">
2222
<div id="@editorId" style="height: @Height; width: 100%;"></div>
23+
@if (output.Any(o => o.Contains("Error loading code editor")))
24+
{
25+
<div class="p-3">
26+
<textarea class="form-control" style="height: @Height; font-family: 'Consolas', 'Monaco', monospace;"
27+
@bind="fallbackCode" placeholder="Code editor failed to load. You can still view the code here.">@InitialCode</textarea>
28+
</div>
29+
}
2330
</div>
2431
</div>
2532

@@ -60,13 +67,24 @@
6067
private List<string> output = new();
6168
private bool isRunning = false;
6269
private string originalCode = "";
70+
private string fallbackCode = "";
6371

6472
protected override async Task OnAfterRenderAsync(bool firstRender)
6573
{
6674
if (firstRender)
6775
{
6876
originalCode = InitialCode;
69-
await JSRuntime.InvokeVoidAsync("codeEditor.initializeEditor", editorId, InitialCode, ReadOnly);
77+
fallbackCode = InitialCode;
78+
try
79+
{
80+
await JSRuntime.InvokeVoidAsync("codeEditor.initializeEditor", editorId, InitialCode, ReadOnly);
81+
}
82+
catch (Exception ex)
83+
{
84+
output.Add($"Error loading code editor: {ex.Message}");
85+
output.Add("Please refresh the page or check your internet connection.");
86+
StateHasChanged();
87+
}
7088
}
7189
}
7290

src/web-tutorial/CSharpTutorial/wwwroot/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<link href="CSharpTutorial.styles.css" rel="stylesheet" />
1313

1414
<!-- Monaco Editor -->
15-
<script src="https://unpkg.com/[email protected]/min/vs/loader.js"></script>
15+
<script src="https://unpkg.com/[email protected]/min/vs/loader.js" onerror="console.error('Failed to load Monaco Editor loader')"></script>
1616
</head>
1717

1818
<body>

src/web-tutorial/CSharpTutorial/wwwroot/js/codeEditor.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ window.codeEditor = {
44

55
// Initialize Monaco Editor
66
initializeEditor: function(containerId, initialCode, readOnly = false) {
7-
return new Promise((resolve) => {
8-
require.config({ paths: { vs: 'https://unpkg.com/[email protected]/min/vs' } });
9-
require(['vs/editor/editor.main'], function () {
7+
return new Promise((resolve, reject) => {
8+
try {
9+
require.config({ paths: { vs: 'https://unpkg.com/[email protected]/min/vs' } });
10+
require(['vs/editor/editor.main'], function () {
1011
const editor = monaco.editor.create(document.getElementById(containerId), {
1112
value: initialCode,
1213
language: 'csharp',
@@ -21,9 +22,16 @@ window.codeEditor = {
2122
wordWrap: 'on'
2223
});
2324

24-
window.codeEditor.editors[containerId] = editor;
25-
resolve(editor);
26-
});
25+
window.codeEditor.editors[containerId] = editor;
26+
resolve(editor);
27+
}, function(error) {
28+
console.error('Failed to load Monaco Editor:', error);
29+
reject(error);
30+
});
31+
} catch (error) {
32+
console.error('Error initializing Monaco Editor:', error);
33+
reject(error);
34+
}
2735
});
2836
},
2937

0 commit comments

Comments
 (0)