Course contentsShow
← Unity Game Development
Lesson 810 of 82812. Multiplayer and DeploymentFree lesson

Implementing Robust Error Handling for Network Connections

Design resilient systems to gracefully handle connection timeouts, lobby disconnections, and failed relay allocations during the session startup.

In this lesson, you will learn how to design resilient connection workflows that prevent your game from hanging when network requests fail during session startup.

When a user attempts to join a lobby or allocate a Relay server, the request relies on external services that can be interrupted by packet loss, server downtime, or timeouts. If you don't explicitly handle these states, your UI might freeze, or the player might be left staring at an infinite "Connecting..." spinner.

The Fail-Fast Design Pattern

To build a robust system, you must treat every asynchronous network operation as a potential point of failure. Instead of assuming success, wrap your connection logic in try-catch blocks and monitor the NetworkManager for disconnection callbacks.

For example, when joining a Relay allocation, you should enforce a local timeout using a CancellationTokenSource. This ensures that if the service doesn't respond within a reasonable timeframe, you can abort the task and notify the player.

public async Task JoinSessionAsync(string joinCode)
{
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
    try 
    {
        // Attempt Relay allocation and transport setup
        var allocation = await RelayService.Instance.JoinAllocationAsync(joinCode);
        // ... (Configure UnityTransport)
        NetworkManager.Singleton.StartClient();
    }
    catch (Exception e)
    {
        Debug.LogError($"Connection failed: {e.Message}");
        // Trigger UI event to return to Main Menu
        UIManager.Instance.ShowError("Unable to join lobby. Please check your connection.");
    }
    finally 
    {
        cts.Dispose();
    }
}

Handling Mid-Startup Disconnects

Errors often occur during the transition between the lobby and the game scene. Use NetworkManager.Singleton.OnClientDisconnectCallback to monitor the startup phase. If the NetworkManager detects a disconnect before the NetworkSceneManager has fully synchronized, your system should automatically trigger a cleanup process—resetting the NetworkManager instance and clearing any stale lobby references. This prevents "ghost" sessions where the client thinks they are still connecting to a server that has already dropped the handshake.

Key Takeaway: Build your connection flow to treat every network request as a time-bound task, and always provide a recovery path that returns the player to a stable UI state when an exception occurs.