testConnection static method

Future<SmtpDiagnosticReport> testConnection(
  1. SmtpConfig config
)

Tests SMTP connectivity without authentication.

Returns a diagnostic report with connection details.

Implementation

static Future<SmtpDiagnosticReport> testConnection(SmtpConfig config) async {
  final report = SmtpDiagnosticReport(config);
  final stopwatch = Stopwatch()..start();

  try {
    // Test basic network connectivity
    report.checkingHost = true;
    final addresses = await InternetAddress.lookup(config.host);
    report.hostResolved = addresses.isNotEmpty;
    report.resolvedAddresses = addresses.map((a) => a.address).toList();

    if (!report.hostResolved) {
      report.error = 'Failed to resolve hostname ${config.host}';
      return report;
    }

    // Test port connectivity
    report.checkingPort = true;
    Socket? socket;
    SecureSocket? secureSocket;

    try {
      if (config.encryption == 'ssl') {
        // Try SSL connection
        secureSocket = await SecureSocket.connect(
          config.host,
          config.port,
          timeout: Duration(seconds: config.timeout),
        ).timeout(
          Duration(seconds: config.timeout),
          onTimeout: () => throw TimeoutException(
            'Connection timeout after ${config.timeout} seconds',
          ),
        );
        report.portOpen = true;
        report.sslSupported = true;
      } else {
        // Try plain connection
        socket = await Socket.connect(
          config.host,
          config.port,
          timeout: Duration(seconds: config.timeout),
        ).timeout(
          Duration(seconds: config.timeout),
          onTimeout: () => throw TimeoutException(
            'Connection timeout after ${config.timeout} seconds',
          ),
        );
        report.portOpen = true;

        // Check if STARTTLS is available
        if (config.encryption == 'tls') {
          report.tlsSupported = true;
        }
      }

      report.connectionTime = stopwatch.elapsedMilliseconds;
      report.success = true;
    } on SocketException catch (e) {
      report.error = 'Socket error: ${e.message}';
      report.portOpen = false;
    } on TimeoutException {
      report.error = 'Connection timeout after ${config.timeout} seconds';
      report.portOpen = false;
    } catch (e) {
      report.error = 'Connection error: $e';
      report.portOpen = false;
    } finally {
      await socket?.close();
      await secureSocket?.close();
    }
  } on SocketException catch (e) {
    report.error = 'Failed to resolve host: ${e.message}';
    report.hostResolved = false;
  } catch (e) {
    report.error = 'Diagnostic error: $e';
  } finally {
    stopwatch.stop();
    report.totalTime = stopwatch.elapsedMilliseconds;
  }

  return report;
}