You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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?
@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.
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)
Steps to reproduce
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.
Further technical details
Npgsql version: 8.0.2
PostgreSQL version: 16
Operating system: Windows, .NET 6
The text was updated successfully, but these errors were encountered: