Skip to content

Commit

Permalink
Remember provider exceptions, use conn. name in exception
Browse files Browse the repository at this point in the history
  • Loading branch information
bmalinowsky committed Jan 30, 2025
1 parent f20c053 commit 0d8c011
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 20 deletions.
37 changes: 21 additions & 16 deletions src/io/calimero/serial/ConnectionFactory.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Calimero 2 - A library for KNX network access
Copyright (c) 2022, 2024 B. Malinowsky
Copyright (c) 2022, 2025 B. Malinowsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -40,11 +40,11 @@
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.ServiceLoader.Provider;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;

import io.calimero.KNXException;
Expand All @@ -71,30 +71,35 @@ public ConnectionFactory(final Class<P> service) {
svcName = service.getName();
}

public C open(final ThrowingFunction<P, C> openFunc) throws KNXException, IOException {
final var tref = new AtomicReference<Throwable>();
final var optC = providers().map(provider -> {
public C open(final String name, final ThrowingFunction<P, C> openFunc) throws KNXException, IOException {
final var providerExceptions = new ArrayList<Throwable>();
final var connOpt = providers().map(provider -> {
try {
final var conn = openFunc.open(provider);
logger.log(Level.DEBUG, "{0} port setup: {1}", provider, conn);
return Optional.of(conn);
}
catch (KNXException | IOException | RuntimeException t) {
tref.set(t);
catch (KNXException | IOException | RuntimeException | ExceptionInInitializerError t) {
logger.log(Level.DEBUG, "{0} unsuccessful: {1}", provider, t.getMessage());
providerExceptions.add(t);
return Optional.<C>empty();
}
}).flatMap(Optional::stream).findFirst();
if (optC.isPresent())
return optC.get();
if (connOpt.isPresent())
return connOpt.get();

final var t = tref.get();
if (t == null)
if (providerExceptions.isEmpty())
throw new KNXException("no service provider available for " + svcName);
if (t instanceof KNXException exception)
throw exception;
if (t instanceof IOException exception)
throw exception;
throw new KNXException("failed to open connection", t);
if (providerExceptions.size() == 1) {
final var x = providerExceptions.get(0);
if (x instanceof final KNXException e)
throw e;
if (x instanceof final IOException e)
throw e;
}
final var t = new KNXException("failed to open connection '" + name + "'");
providerExceptions.forEach(t::addSuppressed);
throw t;
}

public Stream<P> providers() {
Expand Down
2 changes: 1 addition & 1 deletion src/io/calimero/serial/SerialConnectionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static SerialCom open(final String portId, final int baudrate, final Dura
flowControl, readIntervalTimeout, receiveTimeout);

try {
return factory.open(p -> p.open(settings));
return factory.open(portId, p -> p.open(settings));
}
catch (final IOException e) {
throw new KNXException("opening device " + portId, e);
Expand Down
6 changes: 3 additions & 3 deletions src/io/calimero/serial/usb/UsbConnectionFactory.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
Calimero 2 - A library for KNX network access
Copyright (c) 2022, 2024 B. Malinowsky
Copyright (c) 2022, 2025 B. Malinowsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -53,7 +53,7 @@ private UsbConnectionFactory() {}
@SuppressWarnings("resource")
public static UsbConnection open(final Device device) throws KNXException {
try {
return factory.open(p -> p.open(device));
return factory.open(device.toString(), p -> p.open(device));
}
catch (final IOException e) {
throw new KNXException(String.format("open USB connection %s", device), e);
Expand All @@ -63,7 +63,7 @@ public static UsbConnection open(final Device device) throws KNXException {
@SuppressWarnings("resource")
public static UsbConnection open(final String device) throws KNXException {
try {
return factory.open(p -> p.open(device));
return factory.open(device, p -> p.open(device));
}
catch (final IOException e) {
throw new KNXException(String.format("open USB connection %s", device), e);
Expand Down

0 comments on commit 0d8c011

Please sign in to comment.