Skip to content

Commit 8bb8862

Browse files
committed
fix(core,tests,example): resolve all CS8600/CS8602/MSTEST/CA/IDE warnings
Extracted GetRegisteredTypeInfo<T> helper in Helper.cs for proper null-safe GetTypeInfo validation; fixed nullable response assignments in explicit typeInfo overloads and Worker.cs dump methods; added CooperativeCancellation, TestContext.CancellationToken, Assert.IsNotEmpty/IsGreaterThanOrEqualTo, and removed Assert.Fail-in-catch patterns in integration tests.
1 parent 1268ab2 commit 8bb8862

4 files changed

Lines changed: 135 additions & 307 deletions

File tree

ObsWebSocket.Core/ObsWebSocketClient.Helper.cs

Lines changed: 43 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@ private static JsonSerializerOptions CreateHelperOptions()
3030
return options;
3131
}
3232

33+
private static JsonTypeInfo<T> GetRegisteredTypeInfo<T>() where T : class
34+
{
35+
JsonTypeInfo<T>? typeInfo;
36+
try
37+
{
38+
typeInfo = s_helperJsonOptions.GetTypeInfo(typeof(T)) as JsonTypeInfo<T>;
39+
}
40+
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
41+
{
42+
throw new ObsWebSocketException(
43+
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
44+
ex
45+
);
46+
}
47+
return typeInfo ?? throw new ObsWebSocketException(
48+
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type."
49+
);
50+
}
51+
3352
/// <summary>
3453
/// Switches the active Program or Preview scene, optionally setting a specific transition and duration beforehand.
3554
/// Does not restore the previously active transition.
@@ -643,18 +662,7 @@ public static async Task<bool> SetSceneItemEnabledAsync(
643662
)
644663
where T : class
645664
{
646-
JsonTypeInfo<T> typeInfo;
647-
try
648-
{
649-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
650-
}
651-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
652-
{
653-
throw new ObsWebSocketException(
654-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
655-
ex
656-
);
657-
}
665+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
658666
return client.GetSourceFilterSettingsAsync(sourceName, filterName, typeInfo, cancellationToken);
659667
}
660668

@@ -737,18 +745,7 @@ public static Task SetSourceFilterSettingsAsync<T>(
737745
)
738746
where T : class
739747
{
740-
JsonTypeInfo<T> typeInfo;
741-
try
742-
{
743-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
744-
}
745-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
746-
{
747-
throw new ObsWebSocketException(
748-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
749-
ex
750-
);
751-
}
748+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
752749
return client.SetSourceFilterSettingsAsync(sourceName, filterName, settings, typeInfo, overlay, cancellationToken);
753750
}
754751

@@ -839,18 +836,7 @@ public static Task SetSourceFilterSettingsAsync<T>(
839836
)
840837
where T : class
841838
{
842-
JsonTypeInfo<T> typeInfo;
843-
try
844-
{
845-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
846-
}
847-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
848-
{
849-
throw new ObsWebSocketException(
850-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
851-
ex
852-
);
853-
}
839+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
854840
return client.GetInputSettingsAsync(inputName, typeInfo, cancellationToken);
855841
}
856842

@@ -927,18 +913,7 @@ public static Task SetInputSettingsAsync<T>(
927913
)
928914
where T : class
929915
{
930-
JsonTypeInfo<T> typeInfo;
931-
try
932-
{
933-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
934-
}
935-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
936-
{
937-
throw new ObsWebSocketException(
938-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
939-
ex
940-
);
941-
}
916+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
942917
return client.SetInputSettingsAsync(inputName, settings, typeInfo, overlay, cancellationToken);
943918
}
944919

@@ -1033,18 +1008,7 @@ public static Task SetInputSettingsAsync<T>(
10331008
)
10341009
where T : class
10351010
{
1036-
JsonTypeInfo<T> typeInfo;
1037-
try
1038-
{
1039-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1040-
}
1041-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1042-
{
1043-
throw new ObsWebSocketException(
1044-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1045-
ex
1046-
);
1047-
}
1011+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
10481012
return client.CreateInputAsync(inputKind, inputName, settings, typeInfo, sceneName, sceneUuid, sceneItemEnabled, cancellationToken);
10491013
}
10501014

@@ -1128,18 +1092,7 @@ public static Task CreateSourceFilterAsync<T>(
11281092
)
11291093
where T : class
11301094
{
1131-
JsonTypeInfo<T> typeInfo;
1132-
try
1133-
{
1134-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1135-
}
1136-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1137-
{
1138-
throw new ObsWebSocketException(
1139-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1140-
ex
1141-
);
1142-
}
1095+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
11431096
return client.CreateSourceFilterAsync(sourceName, filterName, filterKind, settings, typeInfo, cancellationToken);
11441097
}
11451098

@@ -1167,11 +1120,11 @@ public static Task CreateSourceFilterAsync<T>(
11671120
ArgumentNullException.ThrowIfNull(typeInfo);
11681121
client.EnsureConnected();
11691122

1170-
GetCurrentSceneTransitionResponseData response = await client
1123+
GetCurrentSceneTransitionResponseData? response = await client
11711124
.GetCurrentSceneTransitionAsync(cancellationToken: cancellationToken)
11721125
.ConfigureAwait(false);
11731126

1174-
return response.TransitionSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
1127+
return response?.TransitionSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
11751128
}
11761129

11771130
/// <summary>
@@ -1189,18 +1142,7 @@ public static Task CreateSourceFilterAsync<T>(
11891142
)
11901143
where T : class
11911144
{
1192-
JsonTypeInfo<T> typeInfo;
1193-
try
1194-
{
1195-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1196-
}
1197-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1198-
{
1199-
throw new ObsWebSocketException(
1200-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1201-
ex
1202-
);
1203-
}
1145+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
12041146
return client.GetCurrentSceneTransitionSettingsAsync(typeInfo, cancellationToken);
12051147
}
12061148

@@ -1258,18 +1200,7 @@ public static Task SetCurrentSceneTransitionSettingsAsync<T>(
12581200
)
12591201
where T : class
12601202
{
1261-
JsonTypeInfo<T> typeInfo;
1262-
try
1263-
{
1264-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1265-
}
1266-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1267-
{
1268-
throw new ObsWebSocketException(
1269-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1270-
ex
1271-
);
1272-
}
1203+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
12731204
return client.SetCurrentSceneTransitionSettingsAsync(settings, typeInfo, overlay, cancellationToken);
12741205
}
12751206

@@ -1300,14 +1231,14 @@ public static Task SetCurrentSceneTransitionSettingsAsync<T>(
13001231
ArgumentNullException.ThrowIfNull(typeInfo);
13011232
client.EnsureConnected();
13021233

1303-
GetOutputSettingsResponseData response = await client
1234+
GetOutputSettingsResponseData? response = await client
13041235
.GetOutputSettingsAsync(
13051236
new GetOutputSettingsRequestData(outputName: outputName),
13061237
cancellationToken: cancellationToken
13071238
)
13081239
.ConfigureAwait(false);
13091240

1310-
return response.OutputSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
1241+
return response?.OutputSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
13111242
}
13121243

13131244
/// <summary>
@@ -1327,18 +1258,7 @@ public static Task SetCurrentSceneTransitionSettingsAsync<T>(
13271258
)
13281259
where T : class
13291260
{
1330-
JsonTypeInfo<T> typeInfo;
1331-
try
1332-
{
1333-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1334-
}
1335-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1336-
{
1337-
throw new ObsWebSocketException(
1338-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1339-
ex
1340-
);
1341-
}
1261+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
13421262
return client.GetOutputSettingsAsync(outputName, typeInfo, cancellationToken);
13431263
}
13441264

@@ -1397,18 +1317,7 @@ public static Task SetOutputSettingsAsync<T>(
13971317
)
13981318
where T : class
13991319
{
1400-
JsonTypeInfo<T> typeInfo;
1401-
try
1402-
{
1403-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1404-
}
1405-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1406-
{
1407-
throw new ObsWebSocketException(
1408-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1409-
ex
1410-
);
1411-
}
1320+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
14121321
return client.SetOutputSettingsAsync(outputName, settings, typeInfo, cancellationToken);
14131322
}
14141323

@@ -1436,11 +1345,11 @@ public static Task SetOutputSettingsAsync<T>(
14361345
ArgumentNullException.ThrowIfNull(typeInfo);
14371346
client.EnsureConnected();
14381347

1439-
GetStreamServiceSettingsResponseData response = await client
1348+
GetStreamServiceSettingsResponseData? response = await client
14401349
.GetStreamServiceSettingsAsync(cancellationToken: cancellationToken)
14411350
.ConfigureAwait(false);
14421351

1443-
return response.StreamServiceSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
1352+
return response?.StreamServiceSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
14441353
}
14451354

14461355
/// <summary>
@@ -1458,18 +1367,7 @@ public static Task SetOutputSettingsAsync<T>(
14581367
)
14591368
where T : class
14601369
{
1461-
JsonTypeInfo<T> typeInfo;
1462-
try
1463-
{
1464-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1465-
}
1466-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1467-
{
1468-
throw new ObsWebSocketException(
1469-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1470-
ex
1471-
);
1472-
}
1370+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
14731371
return client.GetStreamServiceSettingsAsync(typeInfo, cancellationToken);
14741372
}
14751373

@@ -1528,18 +1426,7 @@ public static Task SetStreamServiceSettingsAsync<T>(
15281426
)
15291427
where T : class
15301428
{
1531-
JsonTypeInfo<T> typeInfo;
1532-
try
1533-
{
1534-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1535-
}
1536-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1537-
{
1538-
throw new ObsWebSocketException(
1539-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1540-
ex
1541-
);
1542-
}
1429+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
15431430
return client.SetStreamServiceSettingsAsync(streamServiceType, settings, typeInfo, cancellationToken);
15441431
}
15451432

@@ -1570,14 +1457,14 @@ public static Task SetStreamServiceSettingsAsync<T>(
15701457
ArgumentNullException.ThrowIfNull(typeInfo);
15711458
client.EnsureConnected();
15721459

1573-
GetInputDefaultSettingsResponseData response = await client
1460+
GetInputDefaultSettingsResponseData? response = await client
15741461
.GetInputDefaultSettingsAsync(
15751462
new GetInputDefaultSettingsRequestData(inputKind: inputKind),
15761463
cancellationToken: cancellationToken
15771464
)
15781465
.ConfigureAwait(false);
15791466

1580-
return response.DefaultInputSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
1467+
return response?.DefaultInputSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
15811468
}
15821469

15831470
/// <summary>
@@ -1597,18 +1484,7 @@ public static Task SetStreamServiceSettingsAsync<T>(
15971484
)
15981485
where T : class
15991486
{
1600-
JsonTypeInfo<T> typeInfo;
1601-
try
1602-
{
1603-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1604-
}
1605-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1606-
{
1607-
throw new ObsWebSocketException(
1608-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1609-
ex
1610-
);
1611-
}
1487+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
16121488
return client.GetInputDefaultSettingsAsync(inputKind, typeInfo, cancellationToken);
16131489
}
16141490

@@ -1635,14 +1511,14 @@ public static Task SetStreamServiceSettingsAsync<T>(
16351511
ArgumentNullException.ThrowIfNull(typeInfo);
16361512
client.EnsureConnected();
16371513

1638-
GetSourceFilterDefaultSettingsResponseData response = await client
1514+
GetSourceFilterDefaultSettingsResponseData? response = await client
16391515
.GetSourceFilterDefaultSettingsAsync(
16401516
new GetSourceFilterDefaultSettingsRequestData(filterKind: filterKind),
16411517
cancellationToken: cancellationToken
16421518
)
16431519
.ConfigureAwait(false);
16441520

1645-
return response.DefaultFilterSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
1521+
return response?.DefaultFilterSettings is not { } element ? null : JsonSerializer.Deserialize(element, typeInfo);
16461522
}
16471523

16481524
/// <summary>
@@ -1662,18 +1538,7 @@ public static Task SetStreamServiceSettingsAsync<T>(
16621538
)
16631539
where T : class
16641540
{
1665-
JsonTypeInfo<T> typeInfo;
1666-
try
1667-
{
1668-
typeInfo = (JsonTypeInfo<T>)s_helperJsonOptions.GetTypeInfo(typeof(T));
1669-
}
1670-
catch (Exception ex) when (ex is InvalidOperationException or NotSupportedException)
1671-
{
1672-
throw new ObsWebSocketException(
1673-
$"Type '{typeof(T).Name}' is not registered in ObsWebSocketJsonContext. Pass an explicit JsonTypeInfo<T> or use a library-registered settings type.",
1674-
ex
1675-
);
1676-
}
1541+
JsonTypeInfo<T> typeInfo = GetRegisteredTypeInfo<T>();
16771542
return client.GetSourceFilterDefaultSettingsAsync(filterKind, typeInfo, cancellationToken);
16781543
}
16791544

0 commit comments

Comments
 (0)