Skip to content

Commit

Permalink
fix: Log trip and pattern id when negative trip-times occurs in routing.
Browse files Browse the repository at this point in the history
  • Loading branch information
t2gran committed Jan 26, 2024
1 parent 1a2e38d commit a94b34e
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/main/java/org/opentripplanner/framework/lang/ObjectUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opentripplanner.framework.lang;

import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nullable;

/**
Expand Down Expand Up @@ -33,6 +34,18 @@ public static <E, T> T ifNotNull(
return ifNotNull(getter.apply(entity), defaultValue);
}

/**
* Get the value or {@code null}, ignore any exceptions. This is useful if you must traverse
* a long call-chain like {@code a.b().c().d()...} when e.g. logging.
*/
public static <T> T safeGetOrNull(Supplier<T> body) {
try {
return body.get();
} catch (Exception ignore) {
return null;
}
}

public static <T> T requireNotInitialized(T oldValue, T newValue) {
return requireNotInitialized(null, oldValue, newValue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
import java.util.Collection;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opentripplanner.framework.lang.ObjectUtils;
import org.opentripplanner.framework.lang.OtpNumberFormat;
import org.opentripplanner.framework.time.DurationUtils;
import org.opentripplanner.framework.time.TimeUtils;
Expand Down Expand Up @@ -134,12 +136,20 @@ public ToStringBuilder addObj(String name, Object value, @Nullable Object ignore
return addIfNotIgnored(name, value, ignoreValue, Object::toString);
}

/**
* Add the result of the given supplier. If the supplier return {@code null} or an exceptions
* is thrown, then nothing is added - the result is ignored.
*/
public ToStringBuilder addObjOpSafe(String name, Supplier<?> body) {
return addObj(name, ObjectUtils.safeGetOrNull(body));
}

/**
* Use this if you would like a custom toString function to convert the value. If the given value
* is null, then the value is not printed.
* <p>
* Implementation note! The "Op" (Operation) suffix is necessary to separate this from
* {@link #addObj(String, Object, Object)}, when the last argument is null.
* {@link #addObj(String, Object, Object)}, when the last argument is null.
*/
public <T> ToStringBuilder addObjOp(
String name,
Expand Down Expand Up @@ -176,7 +186,7 @@ public ToStringBuilder addDoubles(String name, double[] value, double ignoreValu
return addIt(name, Arrays.toString(value));
}

/** Add collection if not null or not empty, all elements are added */
/** Add the collection if not null or not empty, all elements are added */
public ToStringBuilder addCol(String name, Collection<?> c) {
return addIfNotNull(name, c == null || c.isEmpty() ? null : c);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ public int getSecondsOffset() {
public String toString() {
return ToStringBuilder
.of(TripScheduleWithOffset.class)
.addObj("trip", pattern.debugInfo())
.addObj("info", pattern.debugInfo())
.addObjOpSafe("id", () -> tripTimes.getTrip().getId().toString())
.addObjOpSafe("pattern.id", () -> pattern.getTripPattern().getPattern().getId().toString())
.addServiceTime("depart", secondsOffset + getOriginalTripTimes().getDepartureTime(0))
.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public Route route() {

@Override
public String debugInfo() {
return pattern.logName() + " @" + index;
return pattern.logName() + " #" + index;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.time.Duration;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -48,6 +49,18 @@ void requireNotInitialized() {
assertEquals("Field is already set! Old value: old, new value: new.", ex.getMessage());
}

@Test
void safeGetOrNull() {
assertEquals("test", ObjectUtils.safeGetOrNull(() -> "test"));
assertEquals(3000, ObjectUtils.safeGetOrNull(() -> Duration.ofSeconds(3).toMillis()));
assertNull(ObjectUtils.safeGetOrNull(() -> null));
assertNull(
ObjectUtils.safeGetOrNull(() -> {
throw new NullPointerException("Something went wrong - ignore");
})
);
}

@Test
void toStringTest() {
assertEquals("1", ObjectUtils.toString(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,26 @@ public void addObj() {
);
}

@Test
public void addObjOpSafe() {
assertEquals(
"ToStringBuilderTest{obj: Foo{a: 5, b: 'X'}}",
subject().addObjOpSafe("obj", () -> new Foo(5, "X")).toString()
);
assertEquals("ToStringBuilderTest{}", subject().addObjOpSafe("obj", () -> null).toString());
assertEquals(
"ToStringBuilderTest{}",
subject()
.addObjOpSafe(
"obj",
() -> {
throw new IllegalStateException("Ignore");
}
)
.toString()
);
}

@Test
public void addObjOp() {
var duration = Duration.ofMinutes(1);
Expand Down

0 comments on commit a94b34e

Please sign in to comment.