Skip to content

Commit 263dd4b

Browse files
fix: network manager does not clean up if exception is thrown while starting (#3864)
* fix Fixes the issue where NetworkManager would not clean up if an exception was thrown while it was starting. * Move all connection tests into the Connection folder * Catch any exceptions in PrefabHandler.Instantiate * Add tests for exceptions thrown during startup * Update CHANGELOG * Fix code formatting and remove unused code * Move more connection tests * Fix tests * Update CHANGELOG * Rename test file --------- Co-authored-by: Emma <emma.mcmillan@unity3d.com>
1 parent 8ba35cd commit 263dd4b

21 files changed

+256
-34
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ Additional documentation and release notes are available at [Multiplayer Documen
2929

3030
### Fixed
3131

32-
- Prevented a `NullReferenceException` in `UnityTransport` when using a custom `INetworkStreamDriverConstructor` that doesn't use all the default pipelines and the multiplayer tools package is installed. (#3853)
32+
- Fixed issue where `NetworkManager` was not cleaning itself up if an exception was thrown while starting. (#3864)
3333
- Duplicate transport connection events for the same connection will now do nothing. (#3863)
34+
- Prevented a `NullReferenceException` in `UnityTransport` when using a custom `INetworkStreamDriverConstructor` that doesn't use all the default pipelines and the multiplayer tools package is installed. (#3853)
3435
- Fixed memory leak in `NetworkAnimator` on clients where `RpcTarget` groups were not being properly disposed due to incorrect type casting of `ProxyRpcTargetGroup` to `RpcTargetGroup`.
3536
- Fixed issue when using a client-server topology where a `NetworkList` with owner write permissions was resetting sent time and dirty flags after having been spawned on owning clients that were not the spawn authority. (#3850)
3637
- Fixed an integer overflow that occurred when configuring a large disconnect timeout with Unity Transport. (#3810)

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,17 @@ public bool StartServer()
13231323
}
13241324
ConnectionManager.LocalClient.ClientId = ServerClientId;
13251325

1326-
Initialize(true);
1326+
try
1327+
{
1328+
Initialize(true);
1329+
}
1330+
catch (Exception ex)
1331+
{
1332+
Debug.LogException(ex);
1333+
// Always shutdown to assure everything is cleaned up
1334+
ShutdownInternal();
1335+
return false;
1336+
}
13271337

13281338
try
13291339
{
@@ -1342,11 +1352,12 @@ public bool StartServer()
13421352

13431353
ConnectionManager.TransportFailureEventHandler(true);
13441354
}
1345-
catch (Exception)
1355+
catch (Exception ex)
13461356
{
1347-
ConnectionManager.LocalClient.SetRole(false, false);
1357+
Debug.LogException(ex);
1358+
// Always shutdown to assure everything is cleaned up
1359+
ShutdownInternal();
13481360
IsListening = false;
1349-
throw;
13501361
}
13511362

13521363
return IsListening;
@@ -1373,7 +1384,16 @@ public bool StartClient()
13731384
return false;
13741385
}
13751386

1376-
Initialize(false);
1387+
try
1388+
{
1389+
Initialize(false);
1390+
}
1391+
catch (Exception ex)
1392+
{
1393+
Debug.LogException(ex);
1394+
ShutdownInternal();
1395+
return false;
1396+
}
13771397

13781398
try
13791399
{
@@ -1391,7 +1411,7 @@ public bool StartClient()
13911411
catch (Exception ex)
13921412
{
13931413
Debug.LogException(ex);
1394-
ConnectionManager.LocalClient.SetRole(false, false);
1414+
ShutdownInternal();
13951415
IsListening = false;
13961416
}
13971417

@@ -1419,7 +1439,18 @@ public bool StartHost()
14191439
return false;
14201440
}
14211441

1422-
Initialize(true);
1442+
try
1443+
{
1444+
Initialize(true);
1445+
}
1446+
catch (Exception ex)
1447+
{
1448+
Debug.LogException(ex);
1449+
// Always shutdown to assure everything is cleaned up
1450+
ShutdownInternal();
1451+
return false;
1452+
}
1453+
14231454
try
14241455
{
14251456
IsListening = NetworkConfig.NetworkTransport.StartServer();
@@ -1437,7 +1468,8 @@ public bool StartHost()
14371468
catch (Exception ex)
14381469
{
14391470
Debug.LogException(ex);
1440-
ConnectionManager.LocalClient.SetRole(false, false);
1471+
// Always shutdown to assure everything is cleaned up
1472+
ShutdownInternal();
14411473
IsListening = false;
14421474
}
14431475

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,15 @@ internal NetworkObject HandleNetworkPrefabSpawn(uint networkPrefabAssetHash, ulo
287287
{
288288
if (m_PrefabAssetToPrefabHandlerWithData.TryGetValue(networkPrefabAssetHash, out var prefabInstanceHandler))
289289
{
290-
networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation, instantiationData);
290+
try
291+
{
292+
networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation, instantiationData);
293+
}
294+
catch (Exception ex)
295+
{
296+
Debug.LogException(ex);
297+
return null;
298+
}
291299
}
292300
else
293301
{
@@ -297,7 +305,15 @@ internal NetworkObject HandleNetworkPrefabSpawn(uint networkPrefabAssetHash, ulo
297305
}
298306
else if (m_PrefabAssetToPrefabHandler.TryGetValue(networkPrefabAssetHash, out var prefabInstanceHandler))
299307
{
300-
networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation);
308+
try
309+
{
310+
networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation);
311+
}
312+
catch (Exception ex)
313+
{
314+
Debug.LogException(ex);
315+
return null;
316+
}
301317
}
302318

303319
// Now we must make sure this alternate PrefabAsset spawned in place of the prefab asset with the networkPrefabAssetHash (GlobalObjectIdHash)

com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,21 +155,21 @@ public void UnityTransport_StartServerWithoutAddresses()
155155
[Test]
156156
public void UnityTransport_EmptySecurityStringsShouldThrow([Values("", null)] string cert, [Values("", null)] string secret)
157157
{
158-
var supportingGO = new GameObject();
158+
var supportingGo = new GameObject();
159159
try
160160
{
161-
var networkManager = supportingGO.AddComponent<NetworkManager>(); // NM is required for UTP to work with certificates.
161+
var networkManager = supportingGo.AddComponent<NetworkManager>(); // NM is required for UTP to work with certificates.
162162
networkManager.NetworkConfig = new NetworkConfig();
163-
UnityTransport transport = supportingGO.AddComponent<UnityTransport>();
163+
UnityTransport transport = supportingGo.AddComponent<UnityTransport>();
164164
networkManager.NetworkConfig.NetworkTransport = transport;
165-
transport.Initialize();
165+
transport.Initialize(networkManager);
166166
transport.SetServerSecrets(serverCertificate: cert, serverPrivateKey: secret);
167167

168168
// Use encryption, but don't set certificate and check for exception
169169
transport.UseEncryption = true;
170170
Assert.Throws<System.Exception>(() =>
171171
{
172-
networkManager.StartServer();
172+
transport.StartServer();
173173
});
174174
// Make sure StartServer failed
175175
Assert.False(transport.GetNetworkDriver().IsCreated);
@@ -178,9 +178,9 @@ public void UnityTransport_EmptySecurityStringsShouldThrow([Values("", null)] st
178178
}
179179
finally
180180
{
181-
if (supportingGO != null)
181+
if (supportingGo != null)
182182
{
183-
Object.DestroyImmediate(supportingGO);
183+
Object.DestroyImmediate(supportingGo);
184184
}
185185
}
186186
}

com.unity.netcode.gameobjects/Tests/Runtime/ClientApprovalDenied.cs renamed to com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientApprovalDenied.cs

File renamed without changes.

com.unity.netcode.gameobjects/Tests/Runtime/ClientApprovalDenied.cs.meta renamed to com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientApprovalDenied.cs.meta

File renamed without changes.

com.unity.netcode.gameobjects/Tests/Runtime/ClientOnlyConnectionTests.cs renamed to com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientOnlyConnectionTests.cs

File renamed without changes.

com.unity.netcode.gameobjects/Tests/Runtime/ClientOnlyConnectionTests.cs.meta renamed to com.unity.netcode.gameobjects/Tests/Runtime/Connection/ClientOnlyConnectionTests.cs.meta

File renamed without changes.

com.unity.netcode.gameobjects/Tests/Runtime/ConnectionApproval.cs renamed to com.unity.netcode.gameobjects/Tests/Runtime/Connection/ConnectionApproval.cs

File renamed without changes.

com.unity.netcode.gameobjects/Tests/Runtime/ConnectionApproval.cs.meta renamed to com.unity.netcode.gameobjects/Tests/Runtime/Connection/ConnectionApproval.cs.meta

File renamed without changes.

0 commit comments

Comments
 (0)