Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
pggh opened this issue Mar 2, 2024 · 4 comments · May be fixed by #5664
Open

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

pggh opened this issue Mar 2, 2024 · 4 comments · May be fixed by #5664

Comments

@pggh
Copy link

pggh commented Mar 2, 2024

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

@NinoFloris
Copy link
Member

Also reasonable, marked as enhancement. We should wrap the calls to GetHostAddresses in Connect and ConnectAsync.

@pedrowindisch
Copy link

@NinoFloris

The GetHostAddresses method throws ArgumentOutOfRangeException if the hostname exceeds 255 chars, should we catch and wrap it into a NpgsqlException as well? Or just SocketExceptions?

@pggh
Copy link
Author

pggh commented Apr 2, 2024

@pedrowindisch From my perspective, I would vote to not wrap it. Like ArgumentNull it is a fault of the caller (or local configuration) and not of the DNS or server configuration. Regardless how often it would be retried, it will never work.

@pedrowindisch
Copy link

Hi @pggh, thanks for your input! I agree that such kind of exception is on the caller, and as the documentation states, NpgsqlException is supposed to be thrown when server-related issues occur, which is not really the case with the ArgumentOutOfRange exception I think.

I guess I'll open a PR with the enhancement, and maybe further discussion can take place there? (I'm not well-versed with neither this repo development workflow, nor open source etiquette, so sorry if I'm doing something wrong)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants