Skip to content

SocketException not wrapped into NpgsqlException when hostname can not be resolved. #5606

@pggh

Description

@pggh

Steps to reproduce

using System;
using Npgsql;
class Test1
{
    static int Main(string[] args)
    {
        try {
            var connectionString = new NpgsqlConnectionStringBuilder {
                Host = "hostname.that.does.not.exist",
                //Host = "www.npgsql.org",
                Database = "dbname",
                Username = "user",
                Password = "password",
                Pooling = false,
            };
            var connection = new NpgsqlConnection();
            connection.ConnectionString = connectionString.ConnectionString;
            connection.Open();
        }
        catch (NpgsqlException ex) {
            Console.WriteLine("Expected Exception: " + Environment.NewLine + ex);
        }
        catch (Exception unexpected) {
            Console.WriteLine("Unexpected Exception:" + Environment.NewLine + unexpected);
        }
        return 0;
    }
}

The issue

According to the doc, exceptions related to connection errors should be wrapped in a NpgsqlException exception.
This makes perfectly sense as this will allow catching NpgsqlException at a relatively high level in the code,
dispose all DB related stuff and trying to create a new connection.

However in the example above, a SocketException will be thrown when the hostname can not be resolved.
When the hostname exists but there is no server, a NpgsqlException is thrown.
This inconsistency does not make sense to me.

Unexpected Exception:
System.Net.Sockets.SocketException (11001): No such host is known.
   at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, ValueStopwatch stopwatch)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress, AddressFamily family)
   at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|212_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt)
   at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.UnpooledDataSource.Get(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|42_0(Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.Open()
   at Test1.Main(String[] args) in Test1.cs:line 18

Further technical details

Npgsql version: 8.0.2
PostgreSQL version: 16
Operating system: Windows, .NET 6

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions