JAMES-4030 Carry over Bouncer exceptions

This results on a nack of the underlying mailqueue, thus not loosing the email
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/Bouncer.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/Bouncer.java
index 7ba6556..a50bc4d 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/Bouncer.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/Bouncer.java
@@ -35,9 +35,12 @@
 import org.apache.mailet.AttributeValue;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailetContext;
+import org.apache.mailet.ProcessingState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.fge.lambdas.Throwing;
+
 public class Bouncer {
     private static final Logger LOGGER = LoggerFactory.getLogger(Bouncer.class);
 
@@ -53,18 +56,14 @@
         this.mailetContext = mailetContext;
     }
 
-    public void bounce(Mail mail, Exception ex) {
+    public void bounce(Mail mail, Exception ex) throws MessagingException {
         configuration.getBounceProcessor().ifPresentOrElse(
-            bounceProcessor -> {
+            Throwing.<ProcessingState>consumer(bounceProcessor -> {
                 computeErrorCode(ex).ifPresent(mail::setAttribute);
                 mail.setAttribute(new Attribute(DELIVERY_ERROR, AttributeValue.of(getErrorMsg(ex))));
-                try {
-                    mailetContext.sendMail(mail, bounceProcessor.getValue());
-                } catch (MessagingException e) {
-                    LOGGER.warn("Exception re-inserting failed mail: ", e);
-                }
-            },
-            () -> bounceWithMailetContext(mail, ex));
+                mailetContext.sendMail(mail, bounceProcessor.getValue());
+            }).sneakyThrow(),
+            Throwing.runnable(() -> bounceWithMailetContext(mail, ex)).sneakyThrow());
     }
 
     private Optional<Attribute> computeErrorCode(Exception ex) {
@@ -76,18 +75,12 @@
             .map(code -> new Attribute(DELIVERY_ERROR_CODE, AttributeValue.of(code)));
     }
 
-    private void bounceWithMailetContext(Mail mail, Exception ex) {
+    private void bounceWithMailetContext(Mail mail, Exception ex) throws MessagingException {
         if (!mail.hasSender()) {
             LOGGER.debug("Null Sender: no bounce will be generated for {}", mail.getName());
         } else {
             LOGGER.debug("Sending failure message {}", mail.getName());
-            try {
-                mailetContext.bounce(mail, explanationText(mail, ex));
-            } catch (MessagingException me) {
-                LOGGER.warn("Encountered unexpected messaging exception while bouncing message", me);
-            } catch (Exception e) {
-                LOGGER.warn("Encountered unexpected exception while bouncing message", e);
-            }
+            mailetContext.bounce(mail, explanationText(mail, ex));
         }
     }
 
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java
index 2576b03..9ae75a0 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/DeliveryRunnable.java
@@ -206,7 +206,7 @@
         }
     }
 
-    private void handlePermanentFailure(Mail mail, ExecutionResult executionResult) {
+    private void handlePermanentFailure(Mail mail, ExecutionResult executionResult) throws MessagingException {
         mail.setAttribute(new Attribute(IS_DELIVERY_PERMANENT_ERROR, AttributeValue.of(true)));
         bouncer.bounce(mail, executionResult.getException().orElse(null));
     }
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrer.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrer.java
index c086d39..3d1f8b2 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrer.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrer.java
@@ -218,7 +218,12 @@
         if (!validUnsentAddresses.isEmpty()) {
             if (!invalidAddresses.isEmpty()) {
                 mail.setRecipients(invalidAddresses);
-                bouncer.bounce(mail, sfe);
+                try {
+                    bouncer.bounce(mail, sfe);
+                } catch (MessagingException e) {
+                    LOGGER.warn("Failed bouncing permanently failed recipients, returning full temporarily failure instead", e);
+                    return logAndReturn(mail, ExecutionResult.temporaryFailure(sfe));
+                }
             }
             mail.setRecipients(validUnsentAddresses);
             if (enhancedMessagingException.hasReturnCode()) {