Skip to content

Commit c45b44c

Browse files
authored
refactor(WebClient): add catch exception logic (#5411)
* Revert "fix(EnableIpLocator): WebClientOptions parameter EnableIpLocator not work (#5400)" This reverts commit e5e83f8. # Conflicts: # src/BootstrapBlazor/BootstrapBlazor.csproj * refactor: 增加异常处理逻辑 * refactor: 增加 JSModule 检查逻辑 * chore: bump version 9.3.1-beta25 * test: 更新单元测试
1 parent e1a8f53 commit c45b44c

File tree

7 files changed

+54
-25
lines changed

7 files changed

+54
-25
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.3.1-beta24</Version>
4+
<Version>9.3.1-beta25</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/ConnectionHub/ConnectionHub.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ protected override async Task InvokeInitAsync()
5151
Method = nameof(Callback),
5252
ConnectionId = Guid.NewGuid(),
5353
Interval = options.BeatInterval.TotalMilliseconds,
54-
Url = "ip.axd",
55-
BootstrapBlazorOptions.Value.WebClientOptions.EnableIpLocator
54+
Url = "ip.axd"
5655
});
5756
}
5857
}

src/BootstrapBlazor/Extensions/JSModuleExtensions.cs

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public static async Task<JSModule> LoadModule(this IJSRuntime jsRuntime, string
5050
{
5151
jSObjectReference = await jsRuntime.InvokeAsync<IJSObjectReference>(identifier: "import", fileName);
5252
}
53+
catch (JSDisconnectedException) { }
5354
catch (JSException)
5455
{
5556
#if DEBUG
@@ -58,6 +59,7 @@ public static async Task<JSModule> LoadModule(this IJSRuntime jsRuntime, string
5859
#endif
5960
}
6061
catch (OperationCanceledException) { }
62+
catch (ObjectDisposedException) { }
6163
return new JSModule(jSObjectReference);
6264
}
6365

src/BootstrapBlazor/Services/WebClientService.cs

+7-9
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,17 @@ public async Task<ClientInfo> GetClientInfo()
4343
try
4444
{
4545
_jsModule ??= await runtime.LoadModuleByName("client");
46-
_interop ??= DotNetObjectReference.Create(this);
47-
await _jsModule.InvokeVoidAsync("ping", "ip.axd", _interop, nameof(SetData), new
46+
if (_jsModule != null)
4847
{
49-
options.CurrentValue.WebClientOptions.EnableIpLocator
50-
});
51-
52-
// 等待 SetData 方法执行完毕
53-
await _taskCompletionSource.Task.WaitAsync(TimeSpan.FromSeconds(3));
48+
_interop ??= DotNetObjectReference.Create(this);
49+
await _jsModule.InvokeVoidAsync("ping", "ip.axd", _interop, nameof(SetData));
50+
// 等待 SetData 方法执行完毕
51+
await _taskCompletionSource.Task.WaitAsync(TimeSpan.FromSeconds(3));
52+
}
5453
}
55-
catch (TimeoutException) { }
5654
catch (Exception ex)
5755
{
58-
logger.LogError(ex, "method GetClientInfo failed");
56+
logger.LogError(ex, "{GetClientInfo} throw exception", nameof(GetClientInfo));
5957
}
6058

6159
// 补充 IP 地址信息

src/BootstrapBlazor/wwwroot/modules/client.js

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import "./browser.js"
22
import { execute } from "./ajax.js"
33

4-
export async function ping(url, invoke, method, options) {
5-
const data = await getClientInfo(url, options);
4+
export async function ping(url, invoke, method) {
5+
const data = await getClientInfo(url);
66
await invoke.invokeMethodAsync(method, data)
77
}
88

9-
export async function getClientInfo(url, options) {
9+
export async function getClientInfo(url) {
1010
const info = browser()
1111
let data = {
1212
browser: info.browser + ' ' + info.version,
@@ -17,14 +17,12 @@ export async function getClientInfo(url, options) {
1717
os: info.system + ' ' + info.systemVersion
1818
}
1919

20-
if (options.enableIpLocator === true) {
21-
const result = await execute({
22-
method: 'GET',
23-
url
24-
});
25-
if (result) {
26-
data.ip = result.Ip;
27-
}
20+
const result = await execute({
21+
method: 'GET',
22+
url
23+
});
24+
if (result) {
25+
data.ip = result.Ip;
2826
}
2927
data.id = localStorage.getItem('bb_hub_connection_id') ?? result.Id;
3028
return data;

src/BootstrapBlazor/wwwroot/modules/hub.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Data from "./data.js"
33
import EventHandler from "./event-handler.js";
44

55
export async function init(id, options) {
6-
const { invoke, method, interval = 3000, url, connectionId, enableIpLocator } = options;
6+
const { invoke, method, interval = 3000, url, connectionId } = options;
77
const elKey = 'bb_hub_el_id';
88
if (localStorage.getItem(elKey) === null) {
99
localStorage.setItem(elKey, id);
@@ -34,7 +34,7 @@ export async function init(id, options) {
3434
}
3535
});
3636

37-
const info = await getClientInfo(url, { enableIpLocator: enableIpLocator });
37+
const info = await getClientInfo(url);
3838
info.id = clientId;
3939

4040
const callback = async () => {

test/UnitTest/Extensions/JSModuleExtensionsTest.cs

+32
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ public async Task LoadModule_Ok()
2121

2222
var jsRuntime2 = new JSExceptionJSRuntime();
2323
await Assert.ThrowsAsync<JSException>(() => jsRuntime2.LoadModule("./mock.js", "test"));
24+
25+
var jsRuntime3 = new JSDisconnectedExceptionJSRuntime();
26+
Assert.NotNull(jsRuntime3.LoadModule("./mock.js", "test"));
27+
28+
var jsRuntime4 = new ObjectDisposedExceptionJSRuntime();
29+
Assert.NotNull(jsRuntime4.LoadModule("./mock.js", "test"));
2430
}
2531

2632
[Fact]
@@ -119,4 +125,30 @@ class JSExceptionJSRuntime : IJSRuntime
119125
throw new JSException("test-js-exception");
120126
}
121127
}
128+
129+
class JSDisconnectedExceptionJSRuntime : IJSRuntime
130+
{
131+
public ValueTask<TValue> InvokeAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(string identifier, object?[]? args)
132+
{
133+
throw new JSDisconnectedException("test-js-exception");
134+
}
135+
136+
public ValueTask<TValue> InvokeAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(string identifier, CancellationToken cancellationToken, object?[]? args)
137+
{
138+
throw new JSDisconnectedException("test-js-exception");
139+
}
140+
}
141+
142+
class ObjectDisposedExceptionJSRuntime : IJSRuntime
143+
{
144+
public ValueTask<TValue> InvokeAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(string identifier, object?[]? args)
145+
{
146+
throw new ObjectDisposedException("test-js-exception");
147+
}
148+
149+
public ValueTask<TValue> InvokeAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(string identifier, CancellationToken cancellationToken, object?[]? args)
150+
{
151+
throw new ObjectDisposedException("test-js-exception");
152+
}
153+
}
122154
}

0 commit comments

Comments
 (0)