Explorar el Código

Fix Errors Handling

Lukas Cerny hace 1 año
padre
commit
2730abd9c3

+ 75 - 51
src/main/java/cz/senslog/telemetry/database/repository/MapLogRepository.java

@@ -53,8 +53,7 @@ public class MapLogRepository implements SensLogRepository {
                                 .onFailure(logger::catching);
                     }
                     return Future.succeededFuture(res.rowCount());
-                }).onFailure(logger::catching)
-        ).onFailure(logger::catching);
+                }));
     }
 
     @Override
@@ -78,8 +77,7 @@ public class MapLogRepository implements SensLogRepository {
                         logger.error(res.cause());
                     }
                 })
-                .map(rs -> rs.iterator().next().getInteger(0))
-                .onFailure(logger::error);
+                .map(rs -> rs.iterator().next().getInteger(0));
     }
 
     @Override
@@ -134,7 +132,9 @@ public class MapLogRepository implements SensLogRepository {
         return client.preparedQuery("SELECT unit_id, imei FROM maplog.unit WHERE imei = $1")
                 .execute(Tuple.of(imei))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_SIMPLE_UNIT.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_SIMPLE_UNIT.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Unit IMEI '%s' not found.", imei))));
     }
 
     private static final Function<Row, Sensor> ROW_TO_SENSOR = (row) -> Sensor.of(
@@ -157,7 +157,9 @@ public class MapLogRepository implements SensLogRepository {
                         "WHERE s.sensor_id = $1")
                 .execute(Tuple.of(sensorId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_SENSOR.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_SENSOR.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Sensor ID '%d' not found.", sensorId))));
     }
 
     private static final Function<Row, Sensor> ROW_TO_BASIC_SENSOR = (row) -> Sensor.of(
@@ -177,7 +179,9 @@ public class MapLogRepository implements SensLogRepository {
                         "WHERE s.io_id = $1 AND uts.unit_id = $2")
                 .execute(Tuple.of(ioID, unitId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_BASIC_SENSOR.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_BASIC_SENSOR.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Sensor for Unit(%d) and IO(%d) not found.", unitId, ioID))));
     }
 
     @Override
@@ -252,7 +256,9 @@ public class MapLogRepository implements SensLogRepository {
                         "WHERE s.sensor_id = $3 AND uts.unit_id = $2 AND utc.camp_id = $1")
                 .execute(Tuple.of(campaignId, unitId, sensorId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_SENSOR.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_SENSOR.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Sensor ID '%d' not found in Campaign(%d) and Unit(%d).", sensorId, campaignId, unitId))));
     }
 
     @Override
@@ -279,7 +285,9 @@ public class MapLogRepository implements SensLogRepository {
         return client.preparedQuery("SELECT id, name, uom, uom_link FROM maplog.phenomenon WHERE id = $1")
                 .execute(Tuple.of(phenomenonId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_PHENOMENON.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_PHENOMENON.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Phenomenon ID '%d' not found.", phenomenonId))));
     }
 
     @Override
@@ -295,8 +303,8 @@ public class MapLogRepository implements SensLogRepository {
                                 row.getString("description"),
                                 row.getOffsetDateTime("from_time"),
                                 row.getOffsetDateTime("to_time")
-                        )).collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        )).collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -307,8 +315,8 @@ public class MapLogRepository implements SensLogRepository {
                         .map(row -> Driver.of(
                                 row.getInteger("id"),
                                 row.getString("name")
-                        )).collect(toList()))
-                .onFailure(logger::catching);
+                        )).collect(toList())
+                );
     }
 
     private static final Function<Row, Driver> ROW_TO_DRIVER = (row) -> Driver.of(
@@ -321,7 +329,9 @@ public class MapLogRepository implements SensLogRepository {
         return client.preparedQuery("SELECT id, name FROM maplog.driver WHERE id = $1")
                 .execute(Tuple.of(driverId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_DRIVER.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_DRIVER.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Driver ID '%d' not found.", driverId))));
     }
 
     @Override
@@ -333,9 +343,9 @@ public class MapLogRepository implements SensLogRepository {
                 .map(rs -> StreamSupport.stream(rs.spliterator(), false)
                         .map(row -> Action.of(
                                 row.getInteger("id"),
-                                row.getString("name"))
-                        ).collect(toList()))
-                .onFailure(logger::catching);
+                                row.getString("name")
+                        )).collect(toList())
+                );
     }
 
     @Override
@@ -347,9 +357,9 @@ public class MapLogRepository implements SensLogRepository {
                 .map(rs -> StreamSupport.stream(rs.spliterator(), false)
                         .map(row -> Action.of(
                                 row.getInteger("id"),
-                                row.getString("name"))
-                        ).collect(toList()))
-                .onFailure(logger::catching);
+                                row.getString("name")
+                        )).collect(toList())
+                );
     }
 
     private static final Function<Row, Action> ROW_TO_ACTION = (row) -> Action.of(
@@ -364,7 +374,9 @@ public class MapLogRepository implements SensLogRepository {
                 "WHERE a.id = $1 AND dta.driver_id = $2")
                 .execute(Tuple.of(actionId, driverId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_ACTION.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_ACTION.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Action ID '%d' not found for Driver(%d).", actionId, driverId))));
     }
 
     @Override
@@ -375,7 +387,8 @@ public class MapLogRepository implements SensLogRepository {
                 .execute(Tuple.of(actionId, driverId, unitId))
                 .map(RowSet::iterator)
                 .map(iterator -> iterator.hasNext() ? ROW_TO_ACTION.apply(iterator.next()) : null)
-                .onFailure(logger::catching);
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Action ID '%d' not found for Driver(%d) and Unit(%d).", actionId, driverId, unitId))));
     }
 
     @Override
@@ -391,8 +404,8 @@ public class MapLogRepository implements SensLogRepository {
                                 row.getLong("unit_id"),
                                 row.getOffsetDateTime("from_time"),
                                 row.getOffsetDateTime("to_time")
-                        )).collect(toList()))
-                .onFailure(logger::catching);
+                        )).collect(toList())
+                );
     }
 
     private static final Function<Row, Event> ROW_TO_EVENT = (row) -> Event.of(
@@ -410,7 +423,8 @@ public class MapLogRepository implements SensLogRepository {
                 .execute(Tuple.of(eventId))
                 .map(RowSet::iterator)
                 .map(iterator -> iterator.hasNext() ? ROW_TO_EVENT.apply(iterator.next()) : null)
-                .onFailure(logger::catching);
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Event ID '%d' not found.", eventId))));
     }
 
     @Override
@@ -439,8 +453,8 @@ public class MapLogRepository implements SensLogRepository {
                                 row.getString("name"),
                                 row.getString("imei"),
                                 row.getString("description")
-                        )).collect(toList()))
-                .onFailure(logger::catching);
+                        )).collect(toList())
+                );
     }
 
     @Override
@@ -460,7 +474,8 @@ public class MapLogRepository implements SensLogRepository {
                                 row.getOffsetDateTime("from_time"),
                                 row.getOffsetDateTime("to_time")
                         ))
-                        .collect(Collectors.toList()));
+                        .collect(Collectors.toList())
+                );
     }
 
     private static final Function<Row, CampaignUnit> ROW_TO_CAMPAIGN_UNIT = (row) -> CampaignUnit.of(
@@ -482,7 +497,9 @@ public class MapLogRepository implements SensLogRepository {
                         "WHERE utc.camp_id = $1 AND utc.unit_id = $2")
                 .execute(Tuple.of(campaignId, unitId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_CAMPAIGN_UNIT.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_CAMPAIGN_UNIT.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Unit ID '%d' not found for Campaign(%d).", unitId, campaignId))));
     }
 
     @Override
@@ -493,7 +510,9 @@ public class MapLogRepository implements SensLogRepository {
                         "WHERE dta.driver_id = $1 AND dta.unit_id = $2")
                 .execute(Tuple.of(driverId, unitId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_UNIT.apply(iterator.next()) : null);
+                .map(iterator -> iterator.hasNext() ? ROW_TO_UNIT.apply(iterator.next()) : null)
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Unit ID '%d' not found for Driver(%d).", unitId, driverId))));
     }
 
     @Override
@@ -505,7 +524,8 @@ public class MapLogRepository implements SensLogRepository {
                 .execute(Tuple.of(unitId, driverId, actionId))
                 .map(RowSet::iterator)
                 .map(iterator -> iterator.hasNext() ? ROW_TO_UNIT.apply(iterator.next()) : null)
-                .onFailure(logger::catching);
+                .map(Optional::ofNullable)
+                .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Unit ID '%d' not found for Driver(%d) and Action(%d).", unitId, driverId, actionId))));
     }
 
     @Override
@@ -520,8 +540,8 @@ public class MapLogRepository implements SensLogRepository {
                                 row.getString("name"),
                                 row.getString("imei"),
                                 row.getString("description")
-                        )).collect(toList()))
-                .onFailure(logger::catching);
+                        )).collect(toList())
+                );
     }
 
     @Override
@@ -542,8 +562,7 @@ public class MapLogRepository implements SensLogRepository {
                                 row.getOffsetDateTime("to_time")
                         ))
                         .collect(Collectors.toList())
-                )
-                .onFailure(logger::catching);
+                );
     }
 
     private static final Function<Row, Campaign> ROW_TO_CAMPAIGN = (row) -> Campaign.of(
@@ -558,7 +577,7 @@ public class MapLogRepository implements SensLogRepository {
         return client.preparedQuery("SELECT campaign_id, description, from_time, to_time FROM maplog.campaign WHERE campaign_id = $1")
                 .execute(Tuple.of(campaignId))
                 .map(RowSet::iterator)
-                .map(iterator -> iterator.hasNext() ? ROW_TO_CAMPAIGN.apply(iterator.next()) : null)
+                .map(it -> it.hasNext() ? ROW_TO_CAMPAIGN.apply(it.next()) : null)
                 .map(Optional::ofNullable)
                 .map(p -> p.orElseThrow(() -> new DataNotFoundException(String.format("Campaign ID '%d' not found.", campaignId))));
     }
@@ -587,7 +606,12 @@ public class MapLogRepository implements SensLogRepository {
                         "WHERE uts.sensor_id = $1")
                 .execute(Tuple.of(sensorId))
                 .map(rs -> StreamSupport.stream(rs.spliterator(), false)
-                        .map(ROW_TO_UNIT).collect(Collectors.toList())
+                        .map((row) -> Unit.of(
+                                row.getLong("unit_id"),
+                                row.getString("name"),
+                                row.getString("imei"),
+                                row.getString("description")
+                        )).collect(Collectors.toList())
                 );
     }
 
@@ -648,8 +672,8 @@ public class MapLogRepository implements SensLogRepository {
                                 r.getFloat("speed"),
                                 r.getJsonObject("observed_values")
                         ))
-                        .collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        .collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -711,8 +735,8 @@ public class MapLogRepository implements SensLogRepository {
                                         r.getFloat("angle")),
                                 r.getFloat("speed"),
                                 r.getJsonObject("observed_values")))
-                        .collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        .collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -774,8 +798,8 @@ public class MapLogRepository implements SensLogRepository {
                                         r.getFloat("angle")),
                                 r.getFloat("speed"),
                                 r.getJsonObject("observed_values")))
-                        .collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        .collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -837,8 +861,8 @@ public class MapLogRepository implements SensLogRepository {
                                         r.getFloat("alt"),
                                         r.getFloat("angle")),
                                 r.getFloat("speed")))
-                        .collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        .collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -897,8 +921,8 @@ public class MapLogRepository implements SensLogRepository {
                                         r.getFloat("alt")
                                 )
                         ))
-                        .collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        .collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -956,8 +980,8 @@ public class MapLogRepository implements SensLogRepository {
                                         r.getFloat("alt")
                                 )
                         ))
-                        .collect(Collectors.toList()))
-                .onFailure(logger::catching);
+                        .collect(Collectors.toList())
+                );
     }
 
     @Override
@@ -1016,7 +1040,7 @@ public class MapLogRepository implements SensLogRepository {
                                         r.getFloat("angle")
                                 )
                         ))
-                        .collect(toList()))
-                .onFailure(logger::catching);
+                        .collect(toList())
+                );
     }
 }

+ 12 - 10
src/main/java/cz/senslog/telemetry/server/HttpVertxServer.java

@@ -19,6 +19,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.nio.file.Path;
+import java.util.function.Consumer;
 import java.util.function.Function;
 
 import static java.util.Objects.requireNonNull;
@@ -26,14 +27,6 @@ import static java.util.Objects.requireNonNull;
 public final class HttpVertxServer extends AbstractVerticle {
     private static final Logger logger = LogManager.getLogger(HttpVertxServer.class);
 
-    private static final Function<String,Handler<RoutingContext>> errorHandler = msg -> rc -> rc.response()
-            .setStatusCode(rc.statusCode())
-            .putHeader("Content-Type", "application/json")
-            .end(JsonObject.of(
-                    "code", rc.statusCode(),
-                    "message", rc.failed() ? rc.failure().getMessage() : msg
-            ).encode());
-
     @Override
     public void start(Promise<Void> startPromise) {
         Path openApiUrl = ResourcesUtils.getPath("openAPISpec.yaml");
@@ -100,9 +93,18 @@ public final class HttpVertxServer extends AbstractVerticle {
 //                    mainRouter.route().handler(LoggerHandler.create());
 //                    mainRouter.route().handler(rc -> logger.info("HTTP Request '{}'.", rc.request().absoluteURI()));
 
-                    mainRouter.errorHandler(400, errorHandler.apply("Resource not found."));
 
-                    mainRouter.route().failureHandler(th -> errorHandler.apply(th.failure().getMessage()));
+                    mainRouter.route().failureHandler(cr -> {
+                        logger.error(cr.failure().getMessage());
+                        cr.response()
+                                .putHeader("Content-Type", "application/json")
+                                .setStatusCode(cr.statusCode())
+                                .end(JsonObject.of(
+                                        "code", cr.statusCode(),
+                                        "message", cr.failure().getMessage()
+                                ).encode());
+                    });
+
                     mainRouter.route().handler(CorsHandler.create()
                             .allowedMethod(HttpMethod.GET)
 

+ 75 - 82
src/main/java/cz/senslog/telemetry/server/OpenAPIHandler.java

@@ -1,6 +1,7 @@
 package cz.senslog.telemetry.server;
 
 import cz.senslog.telemetry.app.Application;
+import cz.senslog.telemetry.database.DataNotFoundException;
 import cz.senslog.telemetry.database.SortType;
 import cz.senslog.telemetry.database.repository.SensLogRepository;
 import cz.senslog.telemetry.utils.TernaryCondition;
@@ -15,8 +16,7 @@ import org.apache.logging.log4j.Logger;
 import java.time.OffsetDateTime;
 import java.time.ZoneId;
 import java.util.List;
-import java.util.function.BiFunction;
-import java.util.function.Function;
+import java.util.function.*;
 import java.util.stream.Collectors;
 
 import static java.lang.Boolean.parseBoolean;
@@ -47,6 +47,16 @@ public class OpenAPIHandler {
         return String.format("%s://%s", req.scheme(), req.host());
     }
 
+
+    private static final BiConsumer<Throwable, Consumer<Integer>> throwableToStatusCode = (th, handler) -> {
+        if (th instanceof DataNotFoundException) {
+            handler.accept(404);
+        } else {
+            handler.accept(400);
+        }
+    };
+
+
     public void info(RoutingContext rc) {
         rc.response().end(JsonObject.of(
                     "name", Application.PROJECT_NAME,
@@ -101,8 +111,8 @@ public class OpenAPIHandler {
                                 "description", c.getDescription(),
                                 "fromTime", DATE_TIME_FORMATTER.apply(c.getFromTime(), zone),
                                 "toTime", DATE_TIME_FORMATTER.apply(c.getToTime(), zone)
-                        )).encode())
-                .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitsGET(RoutingContext rc) {
@@ -127,9 +137,8 @@ public class OpenAPIHandler {
                                 "description", u.getDescription(),
                                 "fromTime", DATE_TIME_FORMATTER.apply(u.getFromTime(), zone),
                                 "toTime", DATE_TIME_FORMATTER.apply(u.getToTime(), zone)
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitsObservationsGET(RoutingContext rc) {
@@ -205,9 +214,8 @@ public class OpenAPIHandler {
                                                 "latitude", o.getLocation().getLatitude(),
                                                 "altitude", o.getLocation().getAltitude()),
                                         "observedValues", o.getObservedValues()
-                                )).collect(toList()))
-                )).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                                )).collect(toList())))).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitIdObservationsGET(RoutingContext rc) {
@@ -283,9 +291,8 @@ public class OpenAPIHandler {
                                                         "latitude", o.getLocation().getLatitude(),
                                                         "altitude", o.getLocation().getAltitude()),
                                                 "observedValues", o.getObservedValues()
-                                        )).collect(toList()))
-                        )).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                                        )).collect(toList())))).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitsObservationsLocationsGET(RoutingContext rc) {
@@ -345,9 +352,8 @@ public class OpenAPIHandler {
                                         l.getLocation().getLatitude(),
                                         l.getLocation().getAltitude()
                                 )
-                        )).collect(toList()))
-                )).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        )).collect(toList())))).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitIdLocationsGET(RoutingContext rc) {
@@ -426,9 +432,8 @@ public class OpenAPIHandler {
                                                     l.getLocation().getLatitude(),
                                                     l.getLocation().getAltitude()
                                             )
-                                    )).collect(toList()))
-                    )).encode()))
-                    .onFailure(th -> rc.fail(400, th));
+                                    )).collect(toList())))).encode()))
+                    .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
         } else {
             // TODO implement filter
             /*
@@ -456,8 +461,8 @@ public class OpenAPIHandler {
                                 "name", u.getName(),
                                 "imei", u.getImei(),
                                 "description", u.getDescription()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void unitIdSensorsGET(RoutingContext rc) {
@@ -476,9 +481,8 @@ public class OpenAPIHandler {
                                 "sensorId", s.getSensorId(),
                                 "name", s.getName(),
                                 "type", s.getType()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void unitsGET(RoutingContext rc) {
@@ -496,7 +500,7 @@ public class OpenAPIHandler {
                                 "name", u.getName(),
                                 "description", u.getDescription()
                         ))).collect(toList())).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void unitIdCampaignsGET(RoutingContext rc) {
@@ -520,7 +524,7 @@ public class OpenAPIHandler {
                                 "fromTime", DATE_TIME_FORMATTER.apply(c.getFromTime(), zone),
                                 "toTime", DATE_TIME_FORMATTER.apply(c.getToTime(), zone)
                         ))).collect(toList())).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void sensorIdGET(RoutingContext rc) {
@@ -543,8 +547,8 @@ public class OpenAPIHandler {
                                 "description", s.getDescription(),
                                 "type", s.getType(),
                                 "phenomenon", s.getPhenomenon().getName()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void sensorsGET(RoutingContext rc) {
@@ -562,7 +566,7 @@ public class OpenAPIHandler {
                                 "name", s.getName(),
                                 "description", s.getDescription()
                         ))).collect(toList())).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void sensorIdUnitsGET(RoutingContext rc) {
@@ -581,9 +585,8 @@ public class OpenAPIHandler {
                                 "unitId", u.getUnitId(),
                                 "name", u.getName(),
                                 "description", u.getDescription()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void phenomenonIdGET(RoutingContext rc) {
@@ -603,8 +606,8 @@ public class OpenAPIHandler {
                                 "name", p.getName(),
                                 "uom", p.getUom(),
                                 "uomLink", p.getUomLink()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void phenomenonsGET(RoutingContext rc) {
@@ -621,7 +624,7 @@ public class OpenAPIHandler {
                                 "id", p.getId(),
                                 "name", p.getName()
                         ))).collect(toList())).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void phenomenonIdSensorsGET(RoutingContext rc) {
@@ -640,9 +643,8 @@ public class OpenAPIHandler {
                                 "sensorId", s.getSensorId(),
                                 "name", s.getName(),
                                 "type", s.getType()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitIdGET(RoutingContext rc) {
@@ -672,8 +674,8 @@ public class OpenAPIHandler {
                                 "description", u.getDescription(),
                                 "fromTime", DATE_TIME_FORMATTER.apply(u.getFromTime(), zone),
                                 "toTime", DATE_TIME_FORMATTER.apply(u.getToTime(), zone)
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitIdSensorsGET(RoutingContext rc) {
@@ -693,9 +695,8 @@ public class OpenAPIHandler {
                                 "sensorId", s.getSensorId(),
                                 "name", s.getName(),
                                 "type", s.getType()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitIdSensorIdGET(RoutingContext rc) {
@@ -722,8 +723,8 @@ public class OpenAPIHandler {
                                 "description", s.getDescription(),
                                 "type", s.getType(),
                                 "phenomenon", s.getPhenomenon().getName()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void campaignIdUnitIdSensorIdObservationsGET(RoutingContext rc) {
@@ -800,9 +801,8 @@ public class OpenAPIHandler {
                                                 "longitude", o.getLocation().getLongitude(),
                                                 "latitude", o.getLocation().getLatitude(),
                                                 "altitude", o.getLocation().getAltitude())
-                                )).collect(toList()))
-                )).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                                )).collect(toList())))).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driversGET(RoutingContext rc) {
@@ -819,7 +819,7 @@ public class OpenAPIHandler {
                                 "id", d.getId(),
                                 "name", d.getName()
                         ))).collect(toList())).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdGET(RoutingContext rc) {
@@ -838,8 +838,8 @@ public class OpenAPIHandler {
                         ) : JsonObject.of()).mergeIn(JsonObject.of(
                                 "id", d.getId(),
                                 "name", d.getName()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdUnitsGET(RoutingContext rc) {
@@ -864,9 +864,8 @@ public class OpenAPIHandler {
                                 "unitId", u.getUnitId(),
                                 "name", u.getName(),
                                 "description", u.getDescription()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdUnitIdGET(RoutingContext rc) {
@@ -888,8 +887,8 @@ public class OpenAPIHandler {
                                 "name", u.getName(),
                                 "imei", u.getImei(),
                                 "description", u.getDescription()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdUnitIdActionsGET(RoutingContext rc) {
@@ -908,9 +907,8 @@ public class OpenAPIHandler {
                         ) : JsonObject.of()).mergeIn(JsonObject.of(
                                 "id", a.getId(),
                                 "name", a.getName()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdActionsGET(RoutingContext rc) {
@@ -928,9 +926,8 @@ public class OpenAPIHandler {
                         ) : JsonObject.of()).mergeIn(JsonObject.of(
                                 "id", a.getId(),
                                 "name", a.getName()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdActionIdGET(RoutingContext rc) {
@@ -950,8 +947,8 @@ public class OpenAPIHandler {
                         ) : JsonObject.of()).mergeIn(JsonObject.of(
                                 "id", a.getId(),
                                 "name", a.getName()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdActionIdUnitsGET(RoutingContext rc) {
@@ -971,9 +968,8 @@ public class OpenAPIHandler {
                                 "unitId", u.getUnitId(),
                                 "name", u.getName(),
                                 "description", u.getDescription()
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdActionIdUnitIdGET(RoutingContext rc) {
@@ -997,8 +993,8 @@ public class OpenAPIHandler {
                                 "name", u.getName(),
                                 "imei", u.getImei(),
                                 "description", u.getDescription()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdUnitIdActionIdGET(RoutingContext rc) {
@@ -1020,8 +1016,8 @@ public class OpenAPIHandler {
                         ) : JsonObject.of()).mergeIn(JsonObject.of(
                                 "id", a.getId(),
                                 "name", a.getName()
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void driverIdUnitIdActionIdEventsGET(RoutingContext rc) {
@@ -1045,9 +1041,8 @@ public class OpenAPIHandler {
                                 "id", e.getId(),
                                 "fromTime", DATE_TIME_FORMATTER.apply(e.getFromTime(), zone),
                                 "description", DATE_TIME_FORMATTER.apply(e.getToTime(), zone)
-                        ))).collect(toList())
-                ).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                        ))).collect(toList())).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void eventIdGET(RoutingContext rc) {
@@ -1076,8 +1071,8 @@ public class OpenAPIHandler {
                                 "unitId", e.getUnitId(),
                                 "fromTime", DATE_TIME_FORMATTER.apply(e.getFromTime(), zone),
                                 "description", DATE_TIME_FORMATTER.apply(e.getToTime(), zone)
-                        )).encode())
-                        .onFailure(th -> rc.fail(400, th)));
+                        )).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void eventIdObservationsGET(RoutingContext rc) {
@@ -1152,9 +1147,8 @@ public class OpenAPIHandler {
                                                 "latitude", o.getLocation().getLatitude(),
                                                 "altitude", o.getLocation().getAltitude()),
                                         "observedValues", o.getObservedValues()
-                                )).collect(toList()))
-                )).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                                )).collect(toList())))).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 
     public void eventIdLocationsGET(RoutingContext rc) {
@@ -1228,8 +1222,7 @@ public class OpenAPIHandler {
                                                 l.getLocation().getLatitude(),
                                                 l.getLocation().getAltitude()
                                         )
-                                )).collect(toList()))
-                )).encode()))
-                .onFailure(th -> rc.fail(400, th));
+                                )).collect(toList())))).encode()))
+                .onFailure(th -> throwableToStatusCode.accept(th, code -> rc.fail(code, th)));
     }
 }