diff --git a/service/device/call/api/pom.xml b/service/device/call/api/pom.xml
index b66bf7f5ec1..b9966bcbe11 100644
--- a/service/device/call/api/pom.xml
+++ b/service/device/call/api/pom.xml
@@ -31,5 +31,28 @@
org.eclipse.kapua
kapua-transport-api
+
+
+
+
+ ch.qos.logback
+ logback-core
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+ junit
+ junit
+ test
+
+
+ org.eclipse.kapua
+ kapua-qa-markers
+ test
+
diff --git a/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/DeviceCallExceptionTest.java b/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/DeviceCallExceptionTest.java
new file mode 100644
index 00000000000..cf4291b503e
--- /dev/null
+++ b/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/DeviceCallExceptionTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2023, 2022 Eurotech and/or its affiliates and others
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Eurotech - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.kapua.service.device.call.exception;
+
+import org.eclipse.kapua.qa.markers.junit.JUnitTests;
+import org.eclipse.kapua.service.device.call.exception.model.TestCodesDeviceCallException;
+import org.eclipse.kapua.service.device.call.exception.model.TestDeviceMessage;
+import org.eclipse.kapua.service.device.call.message.DeviceMessage;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.text.MessageFormat;
+
+/**
+ * {@link DeviceCallException}s tests.
+ *
+ * @since 1.0.0
+ */
+@Category(JUnitTests.class)
+public class DeviceCallExceptionTest {
+
+ private final Throwable cause = new Throwable("This is the cause");
+
+ private final Long aTimeout = 15000L;
+ private final DeviceMessage, ?> deviceCallMessage = new TestDeviceMessage();
+
+ @Test
+ public void testDeviceCallErrorCodesHaveMessages() {
+ for (DeviceCallErrorCodes errorCode : DeviceCallErrorCodes.values()) {
+ DeviceCallException deviceCallException = new TestCodesDeviceCallException(errorCode);
+
+ Assert.assertNotEquals("DeviceCallErrorCodes." + errorCode + " doesn't have an error message", "Error: ", deviceCallException.getMessage());
+ Assert.assertNotEquals("DeviceCallErrorCodes." + errorCode + " doesn't have an error message", "Error: ", deviceCallException.getLocalizedMessage());
+ }
+ }
+
+ @Test
+ public void testDeviceCallSendException() {
+ String exceptionMessage = "An error occurred when sending the message: " + deviceCallMessage;
+
+ // Without cause
+ DeviceCallSendException deviceCallSendException = new DeviceCallSendException(deviceCallMessage);
+
+ Assert.assertEquals(DeviceCallErrorCodes.SEND_ERROR, deviceCallSendException.getCode());
+ Assert.assertNull(deviceCallSendException.getCause());
+ Assert.assertEquals(deviceCallMessage, deviceCallSendException.getRequestMessage());
+ Assert.assertEquals(exceptionMessage, deviceCallSendException.getMessage());
+ Assert.assertEquals(exceptionMessage, deviceCallSendException.getLocalizedMessage());
+
+ // With cause
+ exceptionMessage = exceptionMessage + ". Caused by: " + cause.getMessage();
+
+ deviceCallSendException = new DeviceCallSendException(cause, deviceCallMessage);
+
+ Assert.assertEquals(DeviceCallErrorCodes.SEND_ERROR_WITH_CAUSE, deviceCallSendException.getCode());
+ Assert.assertEquals(cause, deviceCallSendException.getCause());
+ Assert.assertEquals(deviceCallMessage, deviceCallSendException.getRequestMessage());
+ Assert.assertEquals(exceptionMessage, deviceCallSendException.getMessage());
+ Assert.assertEquals(exceptionMessage, deviceCallSendException.getLocalizedMessage());
+ }
+
+ @Test
+ public void testDeviceCallTimeoutException() {
+ String exceptionMessage = "The request has not received a response within the timeout of: " + MessageFormat.format("{0}", aTimeout) + "ms";
+
+ DeviceCallTimeoutException deviceCallTimeoutException = new DeviceCallTimeoutException(cause, aTimeout);
+
+ Assert.assertEquals(DeviceCallErrorCodes.TIMEOUT, deviceCallTimeoutException.getCode());
+ Assert.assertEquals(cause, deviceCallTimeoutException.getCause());
+ Assert.assertEquals(aTimeout, deviceCallTimeoutException.getTimeout());
+ Assert.assertEquals(exceptionMessage, deviceCallTimeoutException.getMessage());
+ Assert.assertEquals(exceptionMessage, deviceCallTimeoutException.getLocalizedMessage());
+ }
+}
diff --git a/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/model/TestCodesDeviceCallException.java b/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/model/TestCodesDeviceCallException.java
new file mode 100644
index 00000000000..bb5f0368ea9
--- /dev/null
+++ b/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/model/TestCodesDeviceCallException.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2023, 2022 Eurotech and/or its affiliates and others
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Eurotech - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.kapua.service.device.call.exception.model;
+
+import org.eclipse.kapua.service.device.call.exception.DeviceCallErrorCodes;
+import org.eclipse.kapua.service.device.call.exception.DeviceCallException;
+import org.eclipse.kapua.service.device.call.exception.DeviceCallExceptionTest;
+import org.eclipse.kapua.transport.exception.TransportException;
+
+/**
+ * {@link TransportException} for testing.
+ *
+ * @see DeviceCallExceptionTest#testDeviceCallErrorCodesHaveMessages()
+ * @since 2.0.0
+ */
+public class TestCodesDeviceCallException extends DeviceCallException {
+
+ /**
+ * Constructor.
+ *
+ * @param code The {@link DeviceCallErrorCodes} to test.
+ * @since 2.0.0
+ */
+ public TestCodesDeviceCallException(DeviceCallErrorCodes code) {
+ super(code);
+ }
+}
diff --git a/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/model/TestDeviceMessage.java b/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/model/TestDeviceMessage.java
new file mode 100644
index 00000000000..7ed547f76e3
--- /dev/null
+++ b/service/device/call/api/src/test/java/org/eclipse/kapua/service/device/call/exception/model/TestDeviceMessage.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2023, 2022 Eurotech and/or its affiliates and others
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Eurotech - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.kapua.service.device.call.exception.model;
+
+import org.eclipse.kapua.service.device.call.message.DeviceChannel;
+import org.eclipse.kapua.service.device.call.message.DeviceMessage;
+import org.eclipse.kapua.service.device.call.message.DevicePayload;
+
+import java.util.Date;
+
+/**
+ * {@link DeviceMessage} for testing.
+ *
+ * @since 2.0.0
+ */
+public class TestDeviceMessage implements DeviceMessage {
+ @Override
+ public DeviceChannel getChannel() {
+ return null;
+ }
+
+ @Override
+ public void setChannel(DeviceChannel channel) {
+
+ }
+
+ @Override
+ public DevicePayload getPayload() {
+ return null;
+ }
+
+ @Override
+ public void setPayload(DevicePayload payload) {
+
+ }
+
+ @Override
+ public Date getTimestamp() {
+ return null;
+ }
+
+ @Override
+ public void setTimestamp(Date timestamp) {
+
+ }
+}