Pi4J / pi4j-v2

Pi4J Version 2.0
Apache License 2.0
274 stars 60 forks source link

Pi4J is unusable with lambdas because of all the checked exceptions #65

Closed mheath closed 3 years ago

mheath commented 3 years ago

I'm finding it incredibly difficult to use Pi4J 2.x with lambdas because so many methods are declared to throw Exception.

For example, I find myself often wanting to iterate over a List of configuration objects and then produce a List<DigitalOutput>. So I code something like:

properties.getPumps().stream()
    .map(pumpProperties -> pi4j.create(DigitalOutput.newConfigBuilder(context)
        .id(pumpProperties.getId())
        .name(pumpProperties.getName())
        .address(pumpProperties.getPin())
        .shutdown(DigitalState.LOW)
        .initial(DigitalState.LOW)))
    .collect(Collectors.toList());

but this can't compile because Context.create throws Exception. Can we introduce something like a Pi4jException that extends RuntimeException and forgo using checked exceptions?

I know checked exceptions have been a bike shed issue for a long long time in the Java world but with the introduction of lambda syntax, using checked exceptions has for many (may I be so bold to say most?) Java projects become an anti-pattern.

FDelporte commented 3 years ago

Thanks Mike for this issue report and a very valuable point! I moved it to the pi4j-v2 repo as it should be handled here. Maybe together with #43 .

eitch commented 3 years ago

@mheath i wholeheartedly agree, that checked exceptions should be used very very carefully. In most cases they really do not make sense, but just disturb the writing pattern and don't bring any additional value to the table.

@savageautomate what do you think?

savageautomate commented 3 years ago

I'm very open to changing this behavior. Now is the time to do this on V2 before any first release.

hackerjimbo commented 3 years ago

This also links to my issue about I2C earlier on the issues list. The code seems undecided on whether an I2C write failure should be handled by a return value or by an exception. As it stands no exception is thrown but the return value always indicates success. The diff is:

--- a/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/i2c/PiGpioI2C.java
+++ b/plugins/pi4j-plugin-pigpio/src/main/java/com/pi4j/plugin/pigpio/provider/i2c/PiGpioI2C.java
@@ -151,8 +151,7 @@ public class PiGpioI2C extends I2CBase implements I2C {
     @Override
     public int writeRegister(int register, byte[] data, int offset, int length) throws IOException {
         Objects.checkFromIndexSize(offset, length, data.length);
-        piGpio.i2cWriteI2CBlockData(this.handle, register, data, offset, length);
-        return length;
+        return piGpio.i2cWriteI2CBlockData(this.handle, register, data, offset, length);
     }

     // -------------------------------------------------------------------
FDelporte commented 3 years ago

Has been handled in https://github.com/Pi4J/pi4j-v2/pull/66