Error Handling with try, catch, and finally in C# WinForms

Catch problems, protect your app, and guide the user

In desktop apps, things can go wrong: the user enters invalid data, a file can’t be found, or a device is disconnected. Without proper error handling, your app can crash or behave unpredictably.

In C#, we use try, catch, and finally blocks to detect, handle, and clean up errors — making your WinForms apps safe and user-friendly.


🧱 Basic Structure

try
{
    // Code that might cause an error
}
catch (Exception ex)
{
    // What to do if an error occurs
}
finally
{
    // Code that always runs (optional)
}

⚠ Example: Safe File Reading

private void btnLoad_Click(object sender, EventArgs e)
{
    try
    {
        string content = File.ReadAllText("mydata.txt");
        txtOutput.Text = content;
    }
    catch (FileNotFoundException)
    {
        MessageBox.Show("The file was not found.");
    }
    catch (UnauthorizedAccessException)
    {
        MessageBox.Show("You don’t have permission to open this file.");
    }
    catch (Exception ex)
    {
        MessageBox.Show("Something went wrong: " + ex.Message);
    }
    finally
    {
        // Optional: cleanup or logging
        Console.WriteLine("Load attempt finished.");
    }
}

✅ Multiple catch blocks = more specific handling
finally runs even if an error or success happens


🧠 Why Use try/catch?

BenefitDescription
Prevent app crashesCatch and respond to unexpected problems
Guide the userShow helpful error messages (not raw exceptions)
Clean up resourcesClose files or connections in finally
Improve maintainabilityEasier to debug when something fails

🎯 Example: Input Validation

private void btnDivide_Click(object sender, EventArgs e)
{
    try
    {
        int a = int.Parse(txtA.Text);
        int b = int.Parse(txtB.Text);

        int result = a / b;
        lblResult.Text = $"Result: {result}";
    }
    catch (DivideByZeroException)
    {
        MessageBox.Show("You can't divide by zero!");
    }
    catch (FormatException)
    {
        MessageBox.Show("Please enter valid numbers.");
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error: " + ex.Message);
    }
}

🔁 Using finally

The finally block runs no matter what, making it ideal for cleanup:

FileStream stream = null;

try
{
    stream = File.Open("example.txt", FileMode.Open);
    // Do something with the stream
}
catch (Exception ex)
{
    MessageBox.Show("Problem opening file: " + ex.Message);
}
finally
{
    if (stream != null)
        stream.Close();  // Always close the file
}

✅ Even if an error happens, the file still gets closed


🧪 Quick Challenge

🧩 Create a form that:

  • Accepts two numbers and divides them
  • Catches divide-by-zero and format errors
  • Shows the result in a label
  • Logs each attempt to a file in a finally block

📚 Summary

BlockPurpose
tryRun risky code
catchHandle specific or general exceptions
finallyAlways runs — perfect for cleanup
ex.MessageDetailed message from the caught exception

✅ Best Practices

  • ✅ Catch specific exceptions first (FileNotFoundException, etc.)
  • ✅ Avoid empty catch blocks — always handle or log the error
  • ✅ Use finally to clean up open files, DB connections, etc.
  • ✅ Show friendly messages to users (not raw errors)
  • ✅ Log exceptions to a file or diagnostic tool for dev review

🎓 Want to Go Further?

  • Log errors to a file using StreamWriter
  • Display exception details in a custom error dialog
  • Use Application.ThreadException to catch global UI errors
  • Create a reusable error handler method or class

💬 Want help setting up safe error handling in your form or logging failures for debugging?
Send your current code — We’ll help you wrap it in robust try/catch logic in our WinForms C# Training Course.