You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/06/18 14:46:48 UTC

[james-project] branch master updated (41090084a2 -> 6bceb0a2cc)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


    from 41090084a2 FIX Proxy for SMTPS (#1594)
     new e52fb2c4a2 [CLEAN CODE] JMAP - Make standard error message when invalid json deserialize
     new 6bceb0a2cc Skip retry PropagateLookupRightListener when mailbox not found

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../jmap/event/PropagateLookupRightListener.java   |  5 ++
 .../rfc8621/contract/DelegateSetContract.scala     |  4 +-
 .../contract/EmailQueryMethodContract.scala        | 16 +++----
 .../rfc8621/contract/IdentitySetContract.scala     |  4 +-
 .../contract/MailboxQueryMethodContract.scala      | 10 ++--
 .../contract/MailboxSetMethodContract.scala        | 12 ++---
 .../PushSubscriptionSetMethodContract.scala        |  8 ++--
 .../contract/QuotaChangesMethodContract.scala      |  4 +-
 .../contract/QuotaQueryMethodContract.scala        |  8 ++--
 .../apache/james/jmap/delegation/DelegateSet.scala | 15 ++----
 .../org/apache/james/jmap/mail/IdentitySet.scala   | 13 +-----
 .../scala/org/apache/james/jmap/mail/MDNSend.scala | 17 ++-----
 .../james/jmap/method/DelegateGetMethod.scala      | 10 ++--
 .../james/jmap/method/DelegateSetMethod.scala      |  8 +---
 .../jmap/method/DelegatedAccountGetMethod.scala    | 10 ++--
 .../jmap/method/DelegatedAccountSetMethod.scala    | 11 ++---
 .../james/jmap/method/EmailChangesMethod.scala     |  7 ++-
 .../apache/james/jmap/method/EmailGetMethod.scala  | 11 ++---
 .../james/jmap/method/EmailImportMethod.scala      |  8 ++--
 .../james/jmap/method/EmailParseMethod.scala       | 54 ++++++++++------------
 .../james/jmap/method/EmailQueryMethod.scala       | 11 ++---
 .../apache/james/jmap/method/EmailSetMethod.scala  |  6 +--
 .../jmap/method/EmailSubmissionSetMethod.scala     | 34 +++++---------
 .../james/jmap/method/IdentityChangesMethod.scala  |  8 ++--
 .../james/jmap/method/IdentityGetMethod.scala      |  5 +-
 .../james/jmap/method/IdentitySetMethod.scala      |  7 ++-
 .../apache/james/jmap/method/MDNParseMethod.scala  |  9 ++--
 .../apache/james/jmap/method/MDNSendMethod.scala   |  8 ++--
 .../james/jmap/method/MailboxChangesMethod.scala   |  8 ++--
 .../james/jmap/method/MailboxGetMethod.scala       |  8 ++--
 .../james/jmap/method/MailboxQueryMethod.scala     |  6 +--
 .../jmap/method/MailboxSetCreatePerformer.scala    |  8 +---
 .../james/jmap/method/MailboxSetMethod.scala       |  6 +--
 .../jmap/method/PushSubscriptionGetMethod.scala    |  7 ++-
 .../PushSubscriptionSetCreatePerformer.scala       |  8 +---
 .../jmap/method/PushSubscriptionSetMethod.scala    |  6 +--
 .../james/jmap/method/QuotaChangesMethod.scala     |  6 +--
 .../apache/james/jmap/method/QuotaGetMethod.scala  |  5 +-
 .../james/jmap/method/QuotaQueryMethod.scala       |  8 ++--
 .../james/jmap/method/ThreadChangesMethod.scala    |  6 +--
 .../apache/james/jmap/method/ThreadGetMethod.scala |  7 ++-
 .../jmap/method/VacationResponseGetMethod.scala    |  6 +--
 .../jmap/method/VacationResponseSetMethod.scala    |  6 +--
 .../org/apache/james/jmap/method/package.scala     | 48 +++++++++++++++++++
 44 files changed, 222 insertions(+), 250 deletions(-)
 create mode 100644 server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/package.scala


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 01/02: [CLEAN CODE] JMAP - Make standard error message when invalid json deserialize

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit e52fb2c4a28db6f47e68ae314629f0353f8cdb36
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Fri Jun 16 08:14:09 2023 +0700

    [CLEAN CODE] JMAP - Make standard error message when invalid json deserialize
---
 .../rfc8621/contract/DelegateSetContract.scala     |  4 +-
 .../contract/EmailQueryMethodContract.scala        | 16 +++----
 .../rfc8621/contract/IdentitySetContract.scala     |  4 +-
 .../contract/MailboxQueryMethodContract.scala      | 10 ++--
 .../contract/MailboxSetMethodContract.scala        | 12 ++---
 .../PushSubscriptionSetMethodContract.scala        |  8 ++--
 .../contract/QuotaChangesMethodContract.scala      |  4 +-
 .../contract/QuotaQueryMethodContract.scala        |  8 ++--
 .../apache/james/jmap/delegation/DelegateSet.scala | 15 ++----
 .../org/apache/james/jmap/mail/IdentitySet.scala   | 13 +-----
 .../scala/org/apache/james/jmap/mail/MDNSend.scala | 17 ++-----
 .../james/jmap/method/DelegateGetMethod.scala      | 10 ++--
 .../james/jmap/method/DelegateSetMethod.scala      |  8 +---
 .../jmap/method/DelegatedAccountGetMethod.scala    | 10 ++--
 .../jmap/method/DelegatedAccountSetMethod.scala    | 11 ++---
 .../james/jmap/method/EmailChangesMethod.scala     |  7 ++-
 .../apache/james/jmap/method/EmailGetMethod.scala  | 11 ++---
 .../james/jmap/method/EmailImportMethod.scala      |  8 ++--
 .../james/jmap/method/EmailParseMethod.scala       | 54 ++++++++++------------
 .../james/jmap/method/EmailQueryMethod.scala       | 11 ++---
 .../apache/james/jmap/method/EmailSetMethod.scala  |  6 +--
 .../jmap/method/EmailSubmissionSetMethod.scala     | 34 +++++---------
 .../james/jmap/method/IdentityChangesMethod.scala  |  8 ++--
 .../james/jmap/method/IdentityGetMethod.scala      |  5 +-
 .../james/jmap/method/IdentitySetMethod.scala      |  7 ++-
 .../apache/james/jmap/method/MDNParseMethod.scala  |  9 ++--
 .../apache/james/jmap/method/MDNSendMethod.scala   |  8 ++--
 .../james/jmap/method/MailboxChangesMethod.scala   |  8 ++--
 .../james/jmap/method/MailboxGetMethod.scala       |  8 ++--
 .../james/jmap/method/MailboxQueryMethod.scala     |  6 +--
 .../jmap/method/MailboxSetCreatePerformer.scala    |  8 +---
 .../james/jmap/method/MailboxSetMethod.scala       |  6 +--
 .../jmap/method/PushSubscriptionGetMethod.scala    |  7 ++-
 .../PushSubscriptionSetCreatePerformer.scala       |  8 +---
 .../jmap/method/PushSubscriptionSetMethod.scala    |  6 +--
 .../james/jmap/method/QuotaChangesMethod.scala     |  6 +--
 .../apache/james/jmap/method/QuotaGetMethod.scala  |  5 +-
 .../james/jmap/method/QuotaQueryMethod.scala       |  8 ++--
 .../james/jmap/method/ThreadChangesMethod.scala    |  6 +--
 .../apache/james/jmap/method/ThreadGetMethod.scala |  7 ++-
 .../jmap/method/VacationResponseGetMethod.scala    |  6 +--
 .../jmap/method/VacationResponseSetMethod.scala    |  6 +--
 .../org/apache/james/jmap/method/package.scala     | 48 +++++++++++++++++++
 43 files changed, 217 insertions(+), 250 deletions(-)

diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
index ac675eaa67..5eb3092b3a 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/DelegateSetContract.scala
@@ -226,7 +226,7 @@ trait DelegateSetContract {
            |				"notCreated": {
            |					"4f29": {
            |						"type": "invalidArguments",
-           |						"description": "Missing '/username' property in Delegate object"
+           |						"description": "Missing '/username' property"
            |					}
            |				}
            |			},
@@ -280,7 +280,7 @@ trait DelegateSetContract {
            |				"notCreated": {
            |					"4f29": {
            |						"type": "invalidArguments",
-           |						"description": "'/username' property in Delegate object is not valid: username needs to be represented by a JsString"
+           |						"description": "'/username' property is not valid: username needs to be represented by a JsString"
            |					}
            |				}
            |			},
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
index 15613ffd86..c06761c68e 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
@@ -1951,7 +1951,7 @@ trait EmailQueryMethodContract {
                       |            "error",
                       |            {
                       |                "type": "invalidArguments",
-                      |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.header\\",\\"messages\\":[\\"header filter needs to be an array of one or two strings\\"]}]}"
+                      |                "description": "'/filter/header' property is not valid: header filter needs to be an array of one or two strings"
                       |            },
                       |            "c1"
                       |        ]
@@ -3454,7 +3454,7 @@ trait EmailQueryMethodContract {
         .isEqualTo("""
          {
             "type": "invalidArguments",
-            "description": "{\"errors\":[{\"path\":\"obj.sort[0].property\",\"messages\":[\"error.path.missing\"]}]}"
+            "description": "Missing '/sort(0)/property' property"
           }
          """)
     }
@@ -3551,7 +3551,7 @@ trait EmailQueryMethodContract {
         .isEqualTo("""
          {
             "type": "invalidArguments",
-            "description": "{\"errors\":[{\"path\":\"obj.sort[0].property\",\"messages\":[\"'unsupported' is not a supported sort property\"]}]}"
+            "description": "'/sort(0)/property' property is not valid: 'unsupported' is not a supported sort property"
           }
          """)
     }
@@ -3994,7 +3994,7 @@ trait EmailQueryMethodContract {
              |            "error",
              |            {
              |                "type": "invalidArguments",
-             |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.maxSize\\",\\"messages\\":[\\"Predicate (-1 < 0) did not fail.\\"]}]}"
+             |                "description": "'/filter/maxSize' property is not valid: Predicate (-1 < 0) did not fail."
              |            },
              |            "c1"
              |        ]
@@ -4043,7 +4043,7 @@ trait EmailQueryMethodContract {
              |            "error",
              |            {
              |                "type": "invalidArguments",
-             |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.minSize\\",\\"messages\\":[\\"Predicate (-1 < 0) did not fail.\\"]}]}"
+             |                "description": "'/filter/minSize' property is not valid: Predicate (-1 < 0) did not fail."
              |            },
              |            "c1"
              |        ]
@@ -6936,7 +6936,7 @@ trait EmailQueryMethodContract {
                     |            "error",
                     |            {
                     |                "type": "invalidArguments",
-                    |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"Expecting filterOperator to contain only operator and conditions\\"]}]}"
+                    |                "description": "'/filter' property is not valid: Expecting filterOperator to contain only operator and conditions"
                     |            },
                     |            "c1"
                     |        ]
@@ -6982,7 +6982,7 @@ trait EmailQueryMethodContract {
                     |            "error",
                     |            {
                     |                "type": "invalidArguments",
-                    |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"Expecting filterOperator to contain only operator and conditions\\"]}]}"
+                    |                "description": "'/filter' property is not valid: Expecting filterOperator to contain only operator and conditions"
                     |            },
                     |            "c1"
                     |        ]
@@ -7404,7 +7404,7 @@ trait EmailQueryMethodContract {
         .isEqualTo(
         """{
           |  "type": "invalidArguments",
-          |  "description": "{\"errors\":[{\"path\":\"obj.filter\",\"messages\":[\"These '[unsupported_option, role]' was unsupported filter options\"]}]}"
+          |  "description": "'/filter' property is not valid: These '[unsupported_option, role]' was unsupported filter options"
           |}
           |""".stripMargin)
   }
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/IdentitySetContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/IdentitySetContract.scala
index 55f4c8db35..f83d45a1c9 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/IdentitySetContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/IdentitySetContract.scala
@@ -663,7 +663,7 @@ trait IdentitySetContract {
            |	"notCreated": {
            |		"4f29": {
            |			"type": "invalidArguments",
-           |			"description": "Missing '/email' property in Identity object"
+           |			"description": "Missing '/email' property"
            |		}
            |	}
            |}""".stripMargin)
@@ -721,7 +721,7 @@ trait IdentitySetContract {
            |	"notCreated": {
            |		"4f29": {
            |			"type": "invalidArguments",
-           |			"description": "'/email' property in Identity object is not valid: mail address needs to be represented with a JsString"
+           |			"description": "'/email' property is not valid: mail address needs to be represented with a JsString"
            |		}
            |	}
            |}""".stripMargin)
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxQueryMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxQueryMethodContract.scala
index 25ad0b2bd8..2b77c2db88 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxQueryMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxQueryMethodContract.scala
@@ -340,7 +340,7 @@ trait MailboxQueryMethodContract {
            |            "error",
            |            {
            |                "type": "invalidArguments",
-           |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.role\\",\\"messages\\":[\\"Invalid is not a valid role\\"]}]}"
+           |                "description": "'/filter/role' property is not valid: Invalid is not a valid role"
            |            },
            |            "c1"
            |        ]
@@ -385,7 +385,7 @@ trait MailboxQueryMethodContract {
            |            "error",
            |            {
            |                "type": "invalidArguments",
-           |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.role\\",\\"messages\\":[\\"Expecting a JsString to be representing a role\\"]}]}"
+           |                "description": "'/filter/role' property is not valid: Expecting a JsString to be representing a role"
            |            },
            |            "c1"
            |        ]
@@ -431,7 +431,7 @@ trait MailboxQueryMethodContract {
            |            "error",
            |            {
            |                "type": "invalidArguments",
-           |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.role\\",\\"messages\\":[\\"error.path.missing\\"]}]}"
+           |                "description": "Missing '/filter/role' property"
            |            },
            |            "c1"
            |        ]
@@ -479,7 +479,7 @@ trait MailboxQueryMethodContract {
            |            "error",
            |            {
            |                "type": "invalidArguments",
-           |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"These '[unsupported_option]' was unsupported filter options\\"]}]}"
+           |                "description": "'/filter' property is not valid: These '[unsupported_option]' was unsupported filter options"
            |            },
            |            "c1"
            |        ]
@@ -523,7 +523,7 @@ trait MailboxQueryMethodContract {
            |            "error",
            |            {
            |                "type": "invalidArguments",
-           |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"error.path.missing\\"]}]}"
+           |                "description": "Missing '/filter' property"
            |            },
            |            "c1"
            |        ]
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
index ba755bedfc..261eaab4ed 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
@@ -786,7 +786,7 @@ trait MailboxSetMethodContract {
          |      "notCreated": {
          |        "C42": {
          |          "type": "invalidArguments",
-         |          "description": "Missing '/name' property in mailbox object"
+         |          "description": "Missing '/name' property"
          |        }
          |      }
          |    },
@@ -843,7 +843,7 @@ trait MailboxSetMethodContract {
          |      "notCreated": {
          |        "C42": {
          |          "type": "invalidArguments",
-         |          "description": "'/name' property in mailbox object is not valid: Predicate isEmpty() did not fail."
+         |          "description": "'/name' property is not valid: Predicate isEmpty() did not fail."
          |        }
          |      }
          |    },
@@ -1077,7 +1077,7 @@ trait MailboxSetMethodContract {
          |      "notCreated": {
          |        "C42": {
          |          "type": "invalidArguments",
-         |          "description": "'/parentId' property in mailbox object is not valid: mailboxId does not match Id constraints: Predicate failed: '' contains some invalid characters. Should be [#a-zA-Z0-9-_] and no longer than 255 chars."
+         |          "description": "'/parentId' property is not valid: mailboxId does not match Id constraints: Predicate failed: '' contains some invalid characters. Should be [#a-zA-Z0-9-_] and no longer than 255 chars."
          |        }
          |      }
          |    },
@@ -1471,7 +1471,7 @@ trait MailboxSetMethodContract {
          |			"notCreated": {
          |				"C42": {
          |					"type": "invalidArguments",
-         |					"description": "'/rights/andre@domain.tld(0)' property in mailbox object is not valid: Rights must have size 1"
+         |					"description": "'/rights/andre@domain.tld(0)' property is not valid: Rights must have size 1"
          |				}
          |			}
          |		}, "c1"]
@@ -1529,7 +1529,7 @@ trait MailboxSetMethodContract {
          |			"notCreated": {
          |				"C42": {
          |					"type": "invalidArguments",
-         |					"description": "'/rights/andre@domain.tld(0)' property in mailbox object is not valid: Unknown right 'z'"
+         |					"description": "'/rights/andre@domain.tld(0)' property is not valid: Unknown right 'z'"
          |				}
          |			}
          |		}, "c1"]
@@ -1808,7 +1808,7 @@ trait MailboxSetMethodContract {
          |      "notCreated": {
          |        "C43": {
          |          "type": "invalidArguments",
-         |          "description": "Missing '/name' property in mailbox object"
+         |          "description": "Missing '/name' property"
          |        }
          |      }
          |    },
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/PushSubscriptionSetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/PushSubscriptionSetMethodContract.scala
index ac5a01da6f..773186c0da 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/PushSubscriptionSetMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/PushSubscriptionSetMethodContract.scala
@@ -477,7 +477,7 @@ trait PushSubscriptionSetMethodContract {
            |                "notCreated": {
            |                    "4f29": {
            |                        "type": "invalidArguments",
-           |                        "description": "Missing '/types' property in PushSubscription object"
+           |                        "description": "Missing '/types' property"
            |                    }
            |                }
            |            },
@@ -937,7 +937,7 @@ trait PushSubscriptionSetMethodContract {
            |                "notCreated": {
            |                    "4f29": {
            |                        "type": "invalidArguments",
-           |                        "description": "'/url' property in PushSubscription object is not valid"
+           |                        "description": "'/url' property is not valid"
            |                    }
            |                }
            |            },
@@ -1164,7 +1164,7 @@ trait PushSubscriptionSetMethodContract {
            |                "notCreated": {
            |                    "4f29": {
            |                        "type": "invalidArguments",
-           |                        "description": "'/types(0)' property in PushSubscription object is not valid: Unknown typeName invalid"
+           |                        "description": "'/types(0)' property is not valid: Unknown typeName invalid"
            |                    }
            |                }
            |            },
@@ -1462,7 +1462,7 @@ trait PushSubscriptionSetMethodContract {
            |                "notCreated": {
            |                    "4f29": {
            |                        "type": "invalidArguments",
-           |                        "description": "'/types(0)' property in PushSubscription object is not valid: Unknown typeName invalid"
+           |                        "description": "'/types(0)' property is not valid: Unknown typeName invalid"
            |                    }
            |                }
            |            },
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala
index 86029b2262..dacb2fa693 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala
@@ -341,7 +341,7 @@ trait QuotaChangesMethodContract {
          |            "error",
          |            {
          |                "type": "invalidArguments",
-         |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.sinceState\\",\\"messages\\":[\\"error.path.missing\\"]}]}"
+         |                "description": "Missing '/sinceState' property"
          |            },
          |            "c1"
          |        ]
@@ -382,7 +382,7 @@ trait QuotaChangesMethodContract {
          |            "error",
          |            {
          |                "type": "invalidArguments",
-         |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.sinceState\\",\\"messages\\":[\\"error.expected.uuid\\"]}]}"
+         |                "description": "'/sinceState' property is not valid: error.expected.uuid"
          |            },
          |            "c1"
          |        ]
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaQueryMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaQueryMethodContract.scala
index 19b66125a0..8279966465 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaQueryMethodContract.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaQueryMethodContract.scala
@@ -254,7 +254,7 @@ trait QuotaQueryMethodContract {
          |            "error",
          |            {
          |                "type": "invalidArguments",
-         |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.resourceTypes[0]\\",\\"messages\\":[\\"Unexpected value invalid, only 'count' and 'octets' are managed\\"]}]}"
+         |                "description": "'/filter/resourceTypes(0)' property is not valid: Unexpected value invalid, only 'count' and 'octets' are managed"
          |            },
          |            "c1"
          |        ]
@@ -357,7 +357,7 @@ trait QuotaQueryMethodContract {
          |            "error",
          |            {
          |                "type": "invalidArguments",
-         |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.dataTypes[0]\\",\\"messages\\":[\\"Unexpected value invalid, only 'Mail' are managed\\"]}]}"
+         |                "description": "'/filter/dataTypes(0)' property is not valid: Unexpected value invalid, only 'Mail' are managed"
          |            },
          |            "c1"
          |        ]
@@ -460,7 +460,7 @@ trait QuotaQueryMethodContract {
          |            "error",
          |            {
          |                "type": "invalidArguments",
-         |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter.scope[0]\\",\\"messages\\":[\\"Unexpected value invalidScope, only \'account\' is managed\\"]}]}"
+         |                "description": "'/filter/scope(0)' property is not valid: Unexpected value invalidScope, only 'account' is managed"
          |            },
          |            "c1"
          |        ]
@@ -724,7 +724,7 @@ trait QuotaQueryMethodContract {
          |            "error",
          |            {
          |                "type": "invalidArguments",
-         |                "description": "{\\"errors\\":[{\\"path\\":\\"obj.filter\\",\\"messages\\":[\\"These '[filterName1]' was unsupported filter options\\"]}]}"
+         |                "description": "'/filter' property is not valid: These '[filterName1]' was unsupported filter options"
          |            },
          |            "c1"
          |        ]
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala
index 9e8cacf0eb..899ba8cbea 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/delegation/DelegateSet.scala
@@ -21,9 +21,8 @@ package org.apache.james.jmap.delegation
 
 import org.apache.james.core.Username
 import org.apache.james.jmap.core.Id.Id
-import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.core.{AccountId, Id, SetError, UuidState}
-import org.apache.james.jmap.method.WithAccountId
+import org.apache.james.jmap.method.{WithAccountId, standardError}
 import play.api.libs.json.{JsObject, JsPath, JsonValidationError}
 
 case class DelegateCreationId(id: Id) {
@@ -52,14 +51,6 @@ case class DelegateSetParseException(setError: SetError) extends IllegalArgument
 case class ForbiddenAccountManagementException() extends RuntimeException()
 
 object DelegateSetParseException {
-  def from(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): DelegateSetParseException = {
-    val setError: SetError = errors.head match {
-      case (path, Seq()) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in Delegate object is not valid"))
-      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) =>
-        SetError.invalidArguments(SetErrorDescription(s"Missing '$path' property in Delegate object"))
-      case (path, Seq(JsonValidationError(Seq(message)))) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in Delegate object is not valid: $message"))
-      case (path, _) => SetError.invalidArguments(SetErrorDescription(s"Unknown error on property '$path'"))
-    }
-    DelegateSetParseException(setError)
-  }
+  def from(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): DelegateSetParseException =
+    DelegateSetParseException(standardError(errors))
 }
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/IdentitySet.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/IdentitySet.scala
index 356e82942e..6b44f773e7 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/IdentitySet.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/IdentitySet.scala
@@ -24,7 +24,7 @@ import org.apache.james.jmap.core.Id.Id
 import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.core.{AccountId, Properties, SetError, UuidState}
 import org.apache.james.jmap.method.IdentitySetUpdatePerformer.IdentitySetUpdateResponse
-import org.apache.james.jmap.method.WithAccountId
+import org.apache.james.jmap.method.{WithAccountId, standardError}
 import play.api.libs.json.{JsObject, JsPath, JsonValidationError}
 
 object IdentitySet {
@@ -76,14 +76,5 @@ case class IdentitySetResponse(accountId: AccountId,
 case class IdentitySetParseException(setError: SetError) extends IllegalArgumentException
 
 object IdentitySetParseException {
-  def from(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): IdentitySetParseException = {
-    val setError: SetError = errors.head match {
-      case (path, Seq()) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in Identity object is not valid"))
-      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) =>
-        SetError.invalidArguments(SetErrorDescription(s"Missing '$path' property in Identity object"))
-      case (path, Seq(JsonValidationError(Seq(message)))) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in Identity object is not valid: $message"))
-      case (path, _) => SetError.invalidArguments(SetErrorDescription(s"Unknown error on property '$path'"))
-    }
-    IdentitySetParseException(setError)
-  }
+  def from(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): IdentitySetParseException = IdentitySetParseException(standardError(errors))
 }
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MDNSend.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MDNSend.scala
index f0390ab4bd..c69effc27f 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MDNSend.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MDNSend.scala
@@ -19,16 +19,16 @@
 
 package org.apache.james.jmap.mail
 
-import java.util.UUID
-
 import cats.implicits.toTraverseOps
 import org.apache.james.jmap.core.Id.Id
 import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.core.{AccountId, Id, Properties, SetError}
-import org.apache.james.jmap.method.WithAccountId
+import org.apache.james.jmap.method.{WithAccountId, standardError}
 import org.apache.james.mailbox.model.MessageId
 import play.api.libs.json.{JsObject, JsPath, JsonValidationError}
 
+import java.util.UUID
+
 object MDNSend {
   val MDN_ALREADY_SENT_FLAG: String = "$mdnsent"
 }
@@ -42,15 +42,8 @@ case class MDNSendCreationId(id: Id)
 case class MDNId(value: Id)
 
 object MDNSendRequestInvalidException {
-  def parse(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): MDNSendRequestInvalidException = {
-    val setError: SetError = errors.head match {
-      case (path, Seq()) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in MDNSend object is not valid"))
-      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) => SetError.invalidArguments(SetErrorDescription(s"Missing '$path' property in MDNSend object"))
-      case (path, Seq(JsonValidationError(Seq(message)))) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in MDNSend object is not valid: $message"))
-      case (path, _) => SetError.invalidArguments(SetErrorDescription(s"Unknown error on property '$path'"))
-    }
-    MDNSendRequestInvalidException(setError)
-  }
+  def parse(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): MDNSendRequestInvalidException =
+    MDNSendRequestInvalidException(standardError(errors))
 }
 
 case class MDNSendRequestInvalidException(error: SetError) extends Exception
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateGetMethod.scala
index b56fe00959..16cc71fab8 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateGetMethod.scala
@@ -20,14 +20,12 @@
 package org.apache.james.jmap.method
 
 import eu.timepit.refined.auto._
-import javax.inject.Inject
 import org.apache.james.core.Username
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_DELEGATION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, Properties, SessionTranslator}
-import org.apache.james.jmap.delegation.{Delegate, DelegateGet, DelegateGetRequest, DelegateGetResult, ForbiddenAccountManagementException}
-import org.apache.james.jmap.delegation.{Delegate, DelegateGet, DelegateGetRequest, DelegateGetResult, DelegationId}
-import org.apache.james.jmap.json.{DelegationSerializer, ResponseSerializer}
+import org.apache.james.jmap.delegation.{Delegate, DelegateGet, DelegateGetRequest, DelegateGetResult, DelegationId, ForbiddenAccountManagementException}
+import org.apache.james.jmap.json.DelegationSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
@@ -36,6 +34,7 @@ import org.reactivestreams.Publisher
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
 
+import javax.inject.Inject
 import scala.jdk.OptionConverters._
 
 
@@ -48,8 +47,7 @@ class DelegateGetMethod @Inject()(val metricFactory: MetricFactory,
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JAMES_DELEGATION)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, DelegateGetRequest] =
-    DelegationSerializer.deserializeDelegateGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    DelegationSerializer.deserializeDelegateGetRequest(invocation.arguments.value).asEitherRequest
   override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: DelegateGetRequest): Publisher[InvocationWithContext] = {
     val requestedProperties: Properties = request.properties.getOrElse(DelegateGet.allProperties)
     (requestedProperties -- DelegateGet.allProperties match {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala
index a49692cdc2..2b842908a0 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegateSetMethod.scala
@@ -24,12 +24,11 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JA
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, UuidState}
 import org.apache.james.jmap.delegation.{DelegateSetRequest, DelegateSetResponse, ForbiddenAccountManagementException}
-import org.apache.james.jmap.json.{DelegationSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.DelegationSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.mailbox.MailboxSession.isPrimaryAccount
 import org.apache.james.metrics.api.MetricFactory
-import play.api.libs.json.{JsError, JsSuccess}
 import reactor.core.scala.publisher.SMono
 
 import javax.inject.Inject
@@ -43,10 +42,7 @@ class DelegateSetMethod @Inject()(createPerformer: DelegateSetCreatePerformer,
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JAMES_DELEGATION)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, DelegateSetRequest] =
-    DelegationSerializer.deserializeDelegateSetRequest(invocation.arguments.value) match {
-      case JsSuccess(delegateSetRequest, _) => Right(delegateSetRequest)
-      case errors: JsError => Left(new IllegalArgumentException(ResponseSerializer.serialize(errors).toString))
-    }
+    DelegationSerializer.deserializeDelegateSetRequest(invocation.arguments.value).asEitherRequest
 
   override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: DelegateSetRequest): SMono[InvocationWithContext] =
     if (isPrimaryAccount(mailboxSession)) {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountGetMethod.scala
index 96330d7eae..2e43eb916b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountGetMethod.scala
@@ -20,14 +20,12 @@
 package org.apache.james.jmap.method
 
 import eu.timepit.refined.auto._
-import javax.inject.Inject
 import org.apache.james.core.Username
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_DELEGATION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, Properties, SessionTranslator}
-import org.apache.james.jmap.delegation.{Delegate, DelegatedAccountGet, DelegatedAccountGetRequest, DelegatedAccountGetResult, ForbiddenAccountManagementException}
-import org.apache.james.jmap.delegation.{Delegate, DelegatedAccountGet, DelegatedAccountGetRequest, DelegatedAccountGetResult, DelegationId}
-import org.apache.james.jmap.json.{DelegationSerializer, ResponseSerializer}
+import org.apache.james.jmap.delegation.{Delegate, DelegatedAccountGet, DelegatedAccountGetRequest, DelegatedAccountGetResult, DelegationId, ForbiddenAccountManagementException}
+import org.apache.james.jmap.json.DelegationSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
@@ -36,6 +34,7 @@ import org.reactivestreams.Publisher
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
 
+import javax.inject.Inject
 import scala.jdk.OptionConverters._
 
 class DelegatedAccountGetMethod @Inject()(val metricFactory: MetricFactory,
@@ -47,8 +46,7 @@ class DelegatedAccountGetMethod @Inject()(val metricFactory: MetricFactory,
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JAMES_DELEGATION)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, DelegatedAccountGetRequest] =
-    DelegationSerializer.deserializeDelegatedAccountGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    DelegationSerializer.deserializeDelegatedAccountGetRequest(invocation.arguments.value).asEitherRequest
 
   override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: DelegatedAccountGetRequest): Publisher[InvocationWithContext] = {
     val requestedProperties: Properties = request.properties.getOrElse(DelegatedAccountGet.allProperties)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountSetMethod.scala
index 3f9318fc24..c8fbfe44bd 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/DelegatedAccountSetMethod.scala
@@ -20,19 +20,19 @@
 package org.apache.james.jmap.method
 
 import eu.timepit.refined.auto._
-import javax.inject.Inject
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_DELEGATION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{Invocation, SessionTranslator, UuidState}
 import org.apache.james.jmap.delegation.{DelegatedAccountSetRequest, DelegatedAccountSetResponse, ForbiddenAccountManagementException}
-import org.apache.james.jmap.json.{DelegationSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.DelegationSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.mailbox.MailboxSession.isPrimaryAccount
 import org.apache.james.metrics.api.MetricFactory
-import play.api.libs.json.{JsError, JsSuccess}
 import reactor.core.scala.publisher.SMono
 
+import javax.inject.Inject
+
 class DelegatedAccountSetMethod @Inject()(deletePerformer: DelegatedAccountDeletePerformer,
                                           val metricFactory: MetricFactory,
                                           val sessionSupplier: SessionSupplier,
@@ -41,10 +41,7 @@ class DelegatedAccountSetMethod @Inject()(deletePerformer: DelegatedAccountDelet
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JAMES_DELEGATION)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, DelegatedAccountSetRequest] =
-    DelegationSerializer.deserializeDelegatedAccountSetRequest(invocation.arguments.value) match {
-      case JsSuccess(delegatedAccountSetRequest, _) => Right(delegatedAccountSetRequest)
-      case errors: JsError => Left(new IllegalArgumentException(ResponseSerializer.serialize(errors).toString))
-    }
+    DelegationSerializer.deserializeDelegatedAccountSetRequest(invocation.arguments.value).asEitherRequest
 
   override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: DelegatedAccountSetRequest): SMono[InvocationWithContext] =
     if (isPrimaryAccount(mailboxSession)) {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala
index e5a0e91060..4b9913bbeb 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailChangesMethod.scala
@@ -25,14 +25,14 @@ import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{EmailGetSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailGetSerializer
 import org.apache.james.jmap.mail.{EmailChangesRequest, EmailChangesResponse, HasMoreChanges}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-import javax.inject.Inject
 
+import javax.inject.Inject
 import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 
@@ -74,6 +74,5 @@ class EmailChangesMethod @Inject()(val metricFactory: MetricFactory,
     }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, EmailChangesRequest] =
-    EmailGetSerializer.deserializeEmailChangesRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    EmailGetSerializer.deserializeEmailChangesRequest(invocation.arguments.value).asEitherRequest
 }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala
index ec853b2996..e5d420c09c 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailGetMethod.scala
@@ -18,17 +18,14 @@
  ****************************************************************/
 package org.apache.james.jmap.method
 
-import java.time.ZoneId
-
 import eu.timepit.refined.auto._
-import javax.inject.Inject
 import org.apache.james.jmap.api.change.{EmailChangeRepository, State => JavaState}
 import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.UuidState.INSTANCE
 import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{EmailGetSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailGetSerializer
 import org.apache.james.jmap.mail.{Email, EmailGetRequest, EmailGetResponse, EmailIds, EmailNotFound, EmailView, EmailViewReaderFactory, UnparsedEmailId}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
@@ -38,6 +35,9 @@ import org.slf4j.{Logger, LoggerFactory}
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
 
+import java.time.ZoneId
+import javax.inject.Inject
+
 object EmailGetResults {
   private val logger: Logger = LoggerFactory.getLogger(classOf[EmailGetResults])
 
@@ -92,8 +92,7 @@ class EmailGetMethod @Inject() (readerFactory: EmailViewReaderFactory,
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, EmailGetRequest] =
-    EmailGetSerializer.deserializeEmailGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    EmailGetSerializer.deserializeEmailGetRequest(invocation.arguments.value).asEitherRequest
 
   private def computeResponseInvocation(capabilities: Set[CapabilityIdentifier], request: EmailGetRequest, invocation: Invocation, mailboxSession: MailboxSession): SMono[Invocation] =
     Email.validateProperties(request.properties)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala
index 799cf92838..d2da447b39 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailImportMethod.scala
@@ -27,7 +27,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JA
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, SetError, UuidState}
-import org.apache.james.jmap.json.{EmailSetSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailSetSerializer
 import org.apache.james.jmap.mail.{BlobId, EmailCreationId, EmailCreationResponse, EmailImport, EmailImportRequest, EmailImportResponse, ThreadId, ValidatedEmailImport}
 import org.apache.james.jmap.method.EmailImportMethod.{ImportFailure, ImportResult, ImportResults, ImportSuccess, ImportWithBlob}
 import org.apache.james.jmap.routes.{Blob, BlobNotFoundException, BlobResolvers, ProcessingContext, SessionSupplier}
@@ -42,10 +42,9 @@ import org.apache.james.mime4j.stream.MimeConfig
 import org.apache.james.util.ReactorUtils
 import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.{SFlux, SMono}
-import java.util.Date
 
+import java.util.Date
 import javax.inject.Inject
-
 import scala.util.{Try, Using}
 
 object EmailImportMethod {
@@ -91,8 +90,7 @@ class EmailImportMethod @Inject() (val metricFactory: MetricFactory,
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, JMAP_MAIL)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, EmailImportRequest] =
-    serializer.deserializeEmailImportRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    serializer.deserializeEmailImportRequest(invocation.arguments.value).asEitherRequest
 
   override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: EmailImportRequest): Publisher[InvocationWithContext] =
     for {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailParseMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailParseMethod.scala
index 6d6d65e2ce..2e89d3cc79 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailParseMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailParseMethod.scala
@@ -19,24 +19,23 @@
 
 package org.apache.james.jmap.method
 
-import java.io.InputStream
-
 import eu.timepit.refined.auto._
-import javax.inject.Inject
 import org.apache.james.jmap.api.model.Preview
 import org.apache.james.jmap.api.model.Size.Size
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation._
 import org.apache.james.jmap.core.{Invocation, SessionTranslator}
-import org.apache.james.jmap.json.{EmailGetSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailGetSerializer
 import org.apache.james.jmap.mail.{BlobId, BlobUnParsableException, Email, EmailBody, EmailBodyMetadata, EmailBodyPart, EmailFullViewFactory, EmailHeaders, EmailParseMetadata, EmailParseRequest, EmailParseResponse, EmailParseResults, EmailParseView, HasAttachment}
 import org.apache.james.jmap.routes.{BlobNotFoundException, BlobResolvers, SessionSupplier}
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.util.html.HtmlTextExtractor
-import play.api.libs.json.{JsError, JsObject, JsSuccess, Json}
+import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
 
+import java.io.InputStream
+import javax.inject.Inject
 import scala.util.Try
 
 class EmailParseMethod @Inject()(val blobResolvers: BlobResolvers,
@@ -57,10 +56,7 @@ class EmailParseMethod @Inject()(val blobResolvers: BlobResolvers,
       .map(InvocationWithContext(_, invocation.processingContext))
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, EmailParseRequest] =
-    EmailGetSerializer.deserializeEmailParseRequest(invocation.arguments.value) match {
-      case JsSuccess(parseRequest, _) => Right(parseRequest)
-      case errors: JsError => Left(new IllegalArgumentException(Json.stringify(ResponseSerializer.serialize(errors))))
-    }
+    EmailGetSerializer.deserializeEmailParseRequest(invocation.arguments.value).asEitherRequest
 
   def computeResponseInvocation(request: EmailParseRequest,
                                 invocation: Invocation,
@@ -104,25 +100,25 @@ class EmailParseMethod @Inject()(val blobResolvers: BlobResolvers,
       }
 
   private def parse(request: EmailParseRequest, blobId: BlobId, blobContent: => InputStream, size: Size): SMono[EmailParseResults] = {
-     val result: SMono[EmailParseView] = for {
-       mime4JMessage <- SMono.fromTry(Email.parseStreamAsMime4JMessage(blobContent))
-       bodyStructure <- SMono.fromTry(EmailBodyPart.of(request.bodyProperties, zoneIdProvider.get(), blobId, mime4JMessage))
-       bodyValues <- SMono.fromTry(EmailFullViewFactory.extractBodyValuesForParse(htmlTextExtractor)(bodyStructure, request))
-       preview <- SMono.fromTry(Try(previewFactory.fromMime4JMessage(mime4JMessage)))
-     } yield {
-       EmailParseView(
-         metadata = EmailParseMetadata(blobId = blobId, size = size),
-         header = EmailHeaders.from(zoneIdProvider.get())(mime4JMessage),
-         specificHeaders = EmailHeaders.extractSpecificHeaders(request.properties)(zoneIdProvider.get(), mime4JMessage.getHeader),
-         bodyMetadata = EmailBodyMetadata(hasAttachment = HasAttachment(bodyStructure.attachments.nonEmpty),
-           preview = preview),
-         body = EmailBody(
-           bodyStructure = bodyStructure,
-           textBody = bodyStructure.textBody,
-           htmlBody = bodyStructure.htmlBody,
-           attachments = bodyStructure.attachments,
-           bodyValues = bodyValues))
-     }
-     result.map(EmailParseResults.parsed(blobId, _))
+    val result: SMono[EmailParseView] = for {
+      mime4JMessage <- SMono.fromTry(Email.parseStreamAsMime4JMessage(blobContent))
+      bodyStructure <- SMono.fromTry(EmailBodyPart.of(request.bodyProperties, zoneIdProvider.get(), blobId, mime4JMessage))
+      bodyValues <- SMono.fromTry(EmailFullViewFactory.extractBodyValuesForParse(htmlTextExtractor)(bodyStructure, request))
+      preview <- SMono.fromTry(Try(previewFactory.fromMime4JMessage(mime4JMessage)))
+    } yield {
+      EmailParseView(
+        metadata = EmailParseMetadata(blobId = blobId, size = size),
+        header = EmailHeaders.from(zoneIdProvider.get())(mime4JMessage),
+        specificHeaders = EmailHeaders.extractSpecificHeaders(request.properties)(zoneIdProvider.get(), mime4JMessage.getHeader),
+        bodyMetadata = EmailBodyMetadata(hasAttachment = HasAttachment(bodyStructure.attachments.nonEmpty),
+          preview = preview),
+        body = EmailBody(
+          bodyStructure = bodyStructure,
+          textBody = bodyStructure.textBody,
+          htmlBody = bodyStructure.htmlBody,
+          attachments = bodyStructure.attachments,
+          bodyValues = bodyValues))
+    }
+    result.map(EmailParseResults.parsed(blobId, _))
   }
 }
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
index f1902846ba..d31424ba19 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailQueryMethod.scala
@@ -18,12 +18,8 @@
  ****************************************************************/
 package org.apache.james.jmap.method
 
-import java.time.ZonedDateTime
-
 import cats.implicits._
 import eu.timepit.refined.auto._
-import javax.inject.Inject
-import javax.mail.Flags.Flag.DELETED
 import org.apache.james.jmap.JMAPConfiguration
 import org.apache.james.jmap.api.projections.EmailQueryView
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
@@ -31,7 +27,7 @@ import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.Limit.Limit
 import org.apache.james.jmap.core.Position.Position
 import org.apache.james.jmap.core.{CanCalculateChanges, Invocation, Limit, Position, QueryState, SessionTranslator}
-import org.apache.james.jmap.json.{EmailQuerySerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailQuerySerializer
 import org.apache.james.jmap.mail.{Comparator, EmailQueryRequest, EmailQueryResponse, FilterCondition, UnsupportedRequestParameterException}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.jmap.utils.search.MailboxFilter
@@ -44,6 +40,9 @@ import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.util.streams.{Limit => JavaLimit}
 import reactor.core.scala.publisher.{SFlux, SMono}
 
+import java.time.ZonedDateTime
+import javax.inject.Inject
+import javax.mail.Flags.Flag.DELETED
 import scala.jdk.CollectionConverters._
 
 class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer,
@@ -81,7 +80,7 @@ class EmailQueryMethod @Inject() (serializer: EmailQuerySerializer,
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, EmailQueryRequest] =
     serializer.deserializeEmailQueryRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+      .asEitherRequest
       .flatMap(validateRequestParameters)
 
   private def validateRequestParameters(request: EmailQueryRequest): Either[Exception, EmailQueryRequest] =
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
index 376fda8800..4bdef7d354 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSetMethod.scala
@@ -24,13 +24,14 @@ import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{EmailSetSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailSetSerializer
 import org.apache.james.jmap.mail.{EmailSetRequest, EmailSetResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.mailbox.model.MessageId
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 case class MessageNotFoundException(messageId: MessageId) extends Exception
@@ -77,8 +78,7 @@ class EmailSetMethod @Inject()(serializer: EmailSetSerializer,
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, EmailSetRequest] =
-    serializer.deserialize(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    serializer.deserialize(invocation.arguments.value).asEitherRequest
 
   private def retrieveState(capabilities: Set[CapabilityIdentifier], mailboxSession: MailboxSession): SMono[UuidState] =
     if (capabilities.contains(JAMES_SHARES)) {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
index cf4647e476..7bbbf6597a 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/EmailSubmissionSetMethod.scala
@@ -19,23 +19,16 @@
 
 package org.apache.james.jmap.method
 
-import java.io.InputStream
-
 import cats.implicits._
 import eu.timepit.refined.auto._
 import eu.timepit.refined.refineV
-import javax.annotation.PreDestroy
-import javax.inject.Inject
-import javax.mail.Address
-import javax.mail.Message.RecipientType
-import javax.mail.internet.{InternetAddress, MimeMessage}
 import org.apache.james.core.{MailAddress, Username}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EMAIL_SUBMISSION, JMAP_CORE}
 import org.apache.james.jmap.core.Id.{Id, IdConstraint}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.SetError.{SetErrorDescription, SetErrorType}
 import org.apache.james.jmap.core.{ClientId, Invocation, Properties, ServerId, SessionTranslator, SetError, UuidState}
-import org.apache.james.jmap.json.{EmailSubmissionSetSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.EmailSubmissionSetSerializer
 import org.apache.james.jmap.mail.{EmailSubmissionAddress, EmailSubmissionCreationId, EmailSubmissionCreationRequest, EmailSubmissionCreationResponse, EmailSubmissionId, EmailSubmissionSetRequest, EmailSubmissionSetResponse, Envelope}
 import org.apache.james.jmap.method.EmailSubmissionSetMethod.{CreationFailure, CreationResult, CreationResults, CreationSuccess, LOGGER, MAIL_METADATA_USERNAME_ATTRIBUTE}
 import org.apache.james.jmap.routes.{ProcessingContext, SessionSupplier}
@@ -47,7 +40,6 @@ import org.apache.james.queue.api.MailQueueFactory.SPOOL
 import org.apache.james.queue.api.{MailQueue, MailQueueFactory}
 import org.apache.james.rrt.api.CanSendFrom
 import org.apache.james.server.core.{MailImpl, MimeMessageSource, MimeMessageWrapper}
-import org.apache.james.util.ReactorUtils
 import org.apache.mailet.{Attribute, AttributeName, AttributeValue}
 import org.slf4j.{Logger, LoggerFactory}
 import play.api.libs.json._
@@ -55,6 +47,12 @@ import reactor.core.scala.publisher.{SFlux, SMono}
 import reactor.core.scheduler.Schedulers
 import reactor.util.concurrent.Queues
 
+import java.io.InputStream
+import javax.annotation.PreDestroy
+import javax.inject.Inject
+import javax.mail.Address
+import javax.mail.Message.RecipientType
+import javax.mail.internet.{InternetAddress, MimeMessage}
 import scala.jdk.CollectionConverters._
 import scala.util.{Failure, Success, Try}
 
@@ -190,13 +188,10 @@ class EmailSubmissionSetMethod @Inject()(serializer: EmailSubmissionSetSerialize
         SFlux.concat(SMono.just(explicitInvocation), emailSetCall)
       })
 
-  override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, EmailSubmissionSetRequest] = {
-    val maybeRequestRequest = serializer.deserializeEmailSubmissionSetRequest(invocation.arguments.value) match {
-      case JsSuccess(emailSubmissionSetRequest, _) => Right(emailSubmissionSetRequest)
-      case errors: JsError => Left(new IllegalArgumentException(ResponseSerializer.serialize(errors).toString))
-    }
-    maybeRequestRequest.flatMap(_.validate)
-  }
+  override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, EmailSubmissionSetRequest] =
+    serializer.deserializeEmailSubmissionSetRequest(invocation.arguments.value)
+      .asEitherRequest
+      .flatMap(_.validate)
 
   private def create(request: EmailSubmissionSetRequest,
                      session: MailboxSession,
@@ -241,12 +236,7 @@ class EmailSubmissionSetMethod @Inject()(serializer: EmailSubmissionSetSerialize
       })
 
   private def emailSubmissionSetError(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): SetError =
-    errors.head match {
-      case (path, Seq()) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in EmailSubmission object is not valid"))
-      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) => SetError.invalidArguments(SetErrorDescription(s"Missing '$path' property in EmailSubmission object"))
-      case (path, Seq(JsonValidationError(Seq(message)))) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in EmailSubmission object is not valid: $message"))
-      case (path, _) => SetError.invalidArguments(SetErrorDescription(s"Unknown error on property '$path'"))
-    }
+    standardError(errors)
 
   private def sendEmail(mailboxSession: MailboxSession,
                         request: EmailSubmissionCreationRequest): SMono[(EmailSubmissionCreationResponse, MessageId)] =
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityChangesMethod.scala
index b4207de0b6..3a7a44ed27 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityChangesMethod.scala
@@ -20,11 +20,10 @@
 package org.apache.james.jmap.method
 
 import eu.timepit.refined.auto._
-import javax.inject.Inject
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EMAIL_SUBMISSION}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{IdentitySerializer, ResponseSerializer}
+import org.apache.james.jmap.json.IdentitySerializer
 import org.apache.james.jmap.mail.{HasMoreChanges, IdentityChangesRequest, IdentityChangesResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
@@ -32,6 +31,8 @@ import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.SMono
 
+import javax.inject.Inject
+
 class IdentityChangesMethod @Inject()(val metricFactory: MetricFactory,
                                       val sessionSupplier: SessionSupplier,
                                       val sessionTranslator: SessionTranslator) extends MethodRequiringAccountId[IdentityChangesRequest] {
@@ -61,6 +62,5 @@ class IdentityChangesMethod @Inject()(val metricFactory: MetricFactory,
     }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, IdentityChangesRequest] =
-    IdentitySerializer.deserializeChanges(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    IdentitySerializer.deserializeChanges(invocation.arguments.value).asEitherRequest
 }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala
index acebe60236..4a4ef37ee7 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentityGetMethod.scala
@@ -25,7 +25,7 @@ import org.apache.james.jmap.api.model.{Identity, IdentityId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EMAIL_SUBMISSION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core._
-import org.apache.james.jmap.json.{IdentitySerializer, ResponseSerializer}
+import org.apache.james.jmap.json.IdentitySerializer
 import org.apache.james.jmap.mail.{IdentityGet, IdentityGetRequest, IdentityGetResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
@@ -60,8 +60,7 @@ class IdentityGetMethod @Inject() (identityRepository: IdentityRepository,
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, IdentityGetRequest] =
-    IdentitySerializer.deserialize(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    IdentitySerializer.deserialize(invocation.arguments.value).asEitherRequest
 
   private def getIdentities(request: IdentityGetRequest,
                             mailboxSession: MailboxSession): SMono[IdentityGetResponse] =
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala
index 30e3ce530b..b885c3ab59 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/IdentitySetMethod.scala
@@ -23,12 +23,13 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EMAIL_SUBMISSION, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ClientId, Id, Invocation, ServerId, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{IdentitySerializer, ResponseSerializer}
+import org.apache.james.jmap.json.IdentitySerializer
 import org.apache.james.jmap.mail.{IdentitySetRequest, IdentitySetResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 class IdentitySetMethod @Inject()(createPerformer: IdentitySetCreatePerformer,
@@ -41,9 +42,7 @@ class IdentitySetMethod @Inject()(createPerformer: IdentitySetCreatePerformer,
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, EMAIL_SUBMISSION)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, IdentitySetRequest] =
-    IdentitySerializer.deserializeIdentitySetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
-
+    IdentitySerializer.deserializeIdentitySetRequest(invocation.arguments.value).asEitherRequest
   override def doProcess(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession, request: IdentitySetRequest): SMono[InvocationWithContext] =
     for {
       creationResults <- createPerformer.create(request, mailboxSession)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala
index 74f80dd13d..72bf5b5947 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNParseMethod.scala
@@ -21,9 +21,9 @@ package org.apache.james.jmap.method
 
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL, JMAP_MDN}
-import org.apache.james.jmap.core.{Invocation, SessionTranslator}
 import org.apache.james.jmap.core.Invocation._
-import org.apache.james.jmap.json.{MDNSerializer, ResponseSerializer}
+import org.apache.james.jmap.core.{Invocation, SessionTranslator}
+import org.apache.james.jmap.json.MDNSerializer
 import org.apache.james.jmap.mail.{BlobId, BlobUnParsableException, MDNParseRequest, MDNParseResponse, MDNParseResults, MDNParsed}
 import org.apache.james.jmap.routes.{BlobNotFoundException, BlobResolvers, SessionSupplier}
 import org.apache.james.mailbox.model.{MessageId, MultimailboxesSearchQuery, SearchQuery}
@@ -35,10 +35,9 @@ import org.apache.james.mime4j.dom.Message
 import org.apache.james.mime4j.message.DefaultMessageBuilder
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-import java.io.InputStream
 
+import java.io.InputStream
 import javax.inject.Inject
-
 import scala.jdk.OptionConverters._
 import scala.util.{Try, Using}
 
@@ -60,7 +59,7 @@ class MDNParseMethod @Inject()(serializer: MDNSerializer,
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, MDNParseRequest] =
     serializer.deserializeMDNParseRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+      .asEitherRequest
       .flatMap(_.validate)
 
   def computeResponseInvocation(request: MDNParseRequest,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
index 8f26bdd35e..143547ca6f 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MDNSendMethod.scala
@@ -22,9 +22,9 @@ package org.apache.james.jmap.method
 import eu.timepit.refined.auto._
 import org.apache.james.jmap.api.model.Identity
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL, JMAP_MDN}
-import org.apache.james.jmap.core.{Invocation, SessionTranslator}
 import org.apache.james.jmap.core.Invocation._
-import org.apache.james.jmap.json.{MDNSerializer, ResponseSerializer}
+import org.apache.james.jmap.core.{Invocation, SessionTranslator}
+import org.apache.james.jmap.json.MDNSerializer
 import org.apache.james.jmap.mail.MDN._
 import org.apache.james.jmap.mail.MDNSend.MDN_ALREADY_SENT_FLAG
 import org.apache.james.jmap.mail._
@@ -47,10 +47,10 @@ import org.apache.james.server.core.MailImpl
 import org.apache.james.util.ReactorUtils
 import play.api.libs.json.{JsError, JsObject, JsSuccess}
 import reactor.core.scala.publisher.{SFlux, SMono}
+
 import javax.annotation.PreDestroy
 import javax.inject.Inject
 import javax.mail.internet.MimeMessage
-
 import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 import scala.util.Try
@@ -106,7 +106,7 @@ class MDNSendMethod @Inject()(serializer: MDNSerializer,
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, MDNSendRequest] =
     serializer.deserializeMDNSendRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+      .asEitherRequest
       .flatMap(_.validate)
 
   private def create(identity: Identity,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala
index 0802cd2b5b..b65b4fc1f3 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxChangesMethod.scala
@@ -25,15 +25,15 @@ import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{CapabilityIdentifier, ErrorCode, Invocation, Properties, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.MailboxSerializer
 import org.apache.james.jmap.mail.{HasMoreChanges, MailboxChangesRequest, MailboxChangesResponse}
 import org.apache.james.jmap.method.MailboxChangesMethod.updatedProperties
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
-import javax.inject.Inject
 
+import javax.inject.Inject
 import scala.jdk.CollectionConverters._
 import scala.jdk.OptionConverters._
 
@@ -83,9 +83,7 @@ class MailboxChangesMethod @Inject()(mailboxSerializer: MailboxSerializer,
     })
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, MailboxChangesRequest] =
-    mailboxSerializer.deserializeMailboxChangesRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
-
+    mailboxSerializer.deserializeMailboxChangesRequest(invocation.arguments.value).asEitherRequest
   private def updateProperties(mailboxChanges: MailboxChanges): Option[Properties] =
     if (mailboxChanges.isCountChangesOnly) {
       Some(updatedProperties)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
index 111fddefc3..bacbf3a1f6 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxGetMethod.scala
@@ -26,7 +26,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JA
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{AccountId, CapabilityIdentifier, ErrorCode, Invocation, Properties, SessionTranslator, UuidState}
 import org.apache.james.jmap.http.MailboxesProvisioner
-import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.MailboxSerializer
 import org.apache.james.jmap.mail.{Ids, Mailbox, MailboxFactory, MailboxGet, MailboxGetRequest, MailboxGetResponse, NotFound, PersonalNamespace, Subscriptions, UnparsedMailboxId}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.jmap.utils.quotas.{QuotaLoaderWithPreloadedDefault, QuotaLoaderWithPreloadedDefaultFactory}
@@ -37,8 +37,8 @@ import org.apache.james.mailbox.{MailboxManager, MailboxSession, SubscriptionMan
 import org.apache.james.metrics.api.MetricFactory
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-import javax.inject.Inject
 
+import javax.inject.Inject
 import scala.util.Try
 
 object MailboxGetResults {
@@ -102,9 +102,7 @@ class MailboxGetMethod @Inject() (serializer: MailboxSerializer,
     }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, MailboxGetRequest] =
-    serializer.deserializeMailboxGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
-
+    serializer.deserializeMailboxGetRequest(invocation.arguments.value).asEitherRequest
   private def getMailboxes(capabilities: Set[CapabilityIdentifier],
                            mailboxGetRequest: MailboxGetRequest,
                            mailboxSession: MailboxSession): SFlux[MailboxGetResults] =
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala
index b4ec36f72d..27a8cdd8ae 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxQueryMethod.scala
@@ -22,12 +22,13 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{CanCalculateChanges, ErrorCode, Invocation, Limit, Position, QueryState, SessionTranslator}
-import org.apache.james.jmap.json.{MailboxQuerySerializer, ResponseSerializer}
+import org.apache.james.jmap.json.MailboxQuerySerializer
 import org.apache.james.jmap.mail.{MailboxQueryRequest, MailboxQueryResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.{MailboxSession, SystemMailboxesProvider}
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.{SFlux, SMono}
+
 import javax.inject.Inject
 
 class MailboxQueryMethod @Inject()(systemMailboxesProvider: SystemMailboxesProvider,
@@ -51,8 +52,7 @@ class MailboxQueryMethod @Inject()(systemMailboxesProvider: SystemMailboxesProvi
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, MailboxQueryRequest] =
-    MailboxQuerySerializer.deserialize(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    MailboxQuerySerializer.deserialize(invocation.arguments.value).asEitherRequest
 
   private def processRequest(mailboxSession: MailboxSession, invocation: Invocation, request: MailboxQueryRequest): SMono[Invocation] =
     SFlux.fromPublisher(systemMailboxesProvider.getMailboxByRole(request.filter.role, mailboxSession.getUser))
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
index 4d8b192005..8e2f9c4b4b 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetCreatePerformer.scala
@@ -154,13 +154,7 @@ class MailboxSetCreatePerformer @Inject()(serializer: MailboxSerializer,
       processingContext.recordCreatedId(ClientId(mailboxCreationId.id), ServerId(serverAssignedId))
     }
 
-  private def mailboxSetError(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): SetError =
-    errors.head match {
-      case (path, Seq()) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in mailbox object is not valid"))
-      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) => SetError.invalidArguments(SetErrorDescription(s"Missing '$path' property in mailbox object"))
-      case (path, Seq(JsonValidationError(Seq(message)))) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in mailbox object is not valid: $message"))
-      case (path, _) => SetError.invalidArguments(SetErrorDescription(s"Unknown error on property '$path'"))
-    }
+  private def mailboxSetError(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): SetError = standardError(errors)
 
   private def createMailbox(mailboxSession: MailboxSession,
                             path: MailboxPath,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
index 2dce9e51f5..f5d16fcaad 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
@@ -25,7 +25,7 @@ import org.apache.james.jmap.api.model.{AccountId => JavaAccountId}
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{Invocation, SessionTranslator, SetError, UuidState}
-import org.apache.james.jmap.json.{MailboxSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.MailboxSerializer
 import org.apache.james.jmap.mail.{MailboxSetRequest, MailboxSetResponse}
 import org.apache.james.jmap.method.MailboxSetCreatePerformer.MailboxCreationResults
 import org.apache.james.jmap.method.MailboxSetDeletePerformer.MailboxDeletionResults
@@ -36,6 +36,7 @@ import org.apache.james.mailbox.model.MailboxId
 import org.apache.james.metrics.api.MetricFactory
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 case class MailboxHasMailException(mailboxId: MailboxId) extends Exception
@@ -65,8 +66,7 @@ class MailboxSetMethod @Inject()(serializer: MailboxSerializer,
   } yield InvocationWithContext(response, creationResults._2)
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, MailboxSetRequest] =
-    serializer.deserializeMailboxSetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    serializer.deserializeMailboxSetRequest(invocation.arguments.value).asEitherRequest
 
   private def createResponse(capabilities: Set[CapabilityIdentifier],
                              invocation: Invocation,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala
index 9187531bf3..bdb24de165 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionGetMethod.scala
@@ -25,15 +25,15 @@ import org.apache.james.jmap.api.pushsubscription.PushSubscriptionRepository
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{Ids, Invocation, PushSubscriptionDTO, PushSubscriptionGetRequest, PushSubscriptionGetResponse, SessionTranslator, UnparsedPushSubscriptionId}
-import org.apache.james.jmap.json.{PushSubscriptionSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.PushSubscriptionSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.lifecycle.api.Startable
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
-import javax.inject.Inject
 
+import javax.inject.Inject
 import scala.jdk.CollectionConverters._
 
 case class PushSubscriptionGetResults(results: Seq[PushSubscriptionDTO], notFound: Set[UnparsedPushSubscriptionId]) {
@@ -54,8 +54,7 @@ class PushSubscriptionGetMethod @Inject()(pushSubscriptionSerializer: PushSubscr
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE)
 
   override def getRequest(invocation: Invocation): Either[Exception, PushSubscriptionGetRequest] =
-    pushSubscriptionSerializer.deserializePushSubscriptionGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    pushSubscriptionSerializer.deserializePushSubscriptionGetRequest(invocation.arguments.value).asEitherRequest
 
   override def doProcess(invocation: InvocationWithContext, session: MailboxSession, request: PushSubscriptionGetRequest): SMono[InvocationWithContext] =
     request.validateProperties
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala
index 6a1b460704..4365fc21bc 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetCreatePerformer.scala
@@ -87,13 +87,7 @@ class PushSubscriptionSetCreatePerformer @Inject()(pushSubscriptionRepository: P
     case _ => Some(expires)
   }
 
-  private def pushSubscriptionSetError(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): SetError =
-    errors.head match {
-      case (path, Seq()) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in PushSubscription object is not valid"))
-      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) => SetError.invalidArguments(SetErrorDescription(s"Missing '$path' property in PushSubscription object"))
-      case (path, Seq(JsonValidationError(Seq(message)))) => SetError.invalidArguments(SetErrorDescription(s"'$path' property in PushSubscription object is not valid: $message"))
-      case (path, _) => SetError.invalidArguments(SetErrorDescription(s"Unknown error on property '$path'"))
-    }
+  private def pushSubscriptionSetError(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): SetError = standardError(errors)
 }
 
 class PushSubscriptionSetCreateProcessor @Inject()(webPushClient: WebPushClient) {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala
index e3ca62ebe9..ee758cdf6f 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/PushSubscriptionSetMethod.scala
@@ -23,12 +23,13 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{Invocation, PushSubscriptionSetRequest, PushSubscriptionSetResponse, SessionTranslator}
-import org.apache.james.jmap.json.{PushSubscriptionSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.PushSubscriptionSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.lifecycle.api.Startable
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 class PushSubscriptionSetMethod @Inject()(createPerformer: PushSubscriptionSetCreatePerformer,
@@ -42,8 +43,7 @@ class PushSubscriptionSetMethod @Inject()(createPerformer: PushSubscriptionSetCr
   override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE)
 
   override def getRequest(invocation: Invocation): Either[Exception, PushSubscriptionSetRequest] =
-    pushSubscriptionSerializer.deserializePushSubscriptionSetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    pushSubscriptionSerializer.deserializePushSubscriptionSetRequest(invocation.arguments.value).asEitherRequest
 
   override def doProcess(invocation: InvocationWithContext, mailboxSession: MailboxSession, request: PushSubscriptionSetRequest): SMono[InvocationWithContext] =
     for {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala
index 87543161eb..8e7fe530c9 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaChangesMethod.scala
@@ -27,7 +27,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JM
 import org.apache.james.jmap.core.Id.Id
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{QuotaSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.QuotaSerializer
 import org.apache.james.jmap.mail.{JmapQuota, QuotaChangesRequest, QuotaChangesResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.quota.{QuotaManager, UserQuotaRootResolver}
 import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 class QuotaChangesMethod @Inject()(val metricFactory: MetricFactory,
@@ -64,8 +65,7 @@ class QuotaChangesMethod @Inject()(val metricFactory: MetricFactory,
       }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, QuotaChangesRequest] =
-    QuotaSerializer.deserializeQuotaChangesRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    QuotaSerializer.deserializeQuotaChangesRequest(invocation.arguments.value).asEitherRequest
 }
 
 case class QuotaChangesResolver(private val quotaManager: QuotaManager,
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala
index 002418241f..c659a22049 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaGetMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.core.Username
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JAMES_SHARES, JMAP_CORE, JMAP_QUOTA}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, Properties, SessionTranslator}
-import org.apache.james.jmap.json.{QuotaSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.QuotaSerializer
 import org.apache.james.jmap.mail.{CountResourceType, JmapQuota, OctetsResourceType, QuotaGetRequest, QuotaIdFactory, QuotaResponseGetResult}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.lifecycle.api.Startable
@@ -68,8 +68,7 @@ class QuotaGetMethod @Inject()(val metricFactory: MetricFactory,
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, QuotaGetRequest] =
-    QuotaSerializer.deserializeQuotaGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    QuotaSerializer.deserializeQuotaGetRequest(invocation.arguments.value).asEitherRequest
 
   private def getQuotaGetResponse(request: QuotaGetRequest, username: Username, capabilities: Set[CapabilityIdentifier]): SMono[QuotaResponseGetResult] =
     jmapQuotaManagerWrapper.list(username, capabilities)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala
index da484f27fe..8d32198587 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/QuotaQueryMethod.scala
@@ -23,15 +23,15 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_QUOTA}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{CanCalculateChanges, ErrorCode, Invocation, Limit, Position, QueryState, SessionTranslator}
-import org.apache.james.jmap.json.{QuotaSerializer, ResponseSerializer}
+import org.apache.james.jmap.json.QuotaSerializer
 import org.apache.james.jmap.mail.{JmapQuota, QuotaQueryFilter, QuotaQueryRequest, QuotaQueryResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.mailbox.quota.{QuotaManager, UserQuotaRootResolver}
 import org.apache.james.metrics.api.MetricFactory
 import org.reactivestreams.Publisher
-import play.api.libs.json.JsError
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 class QuotaQueryMethod @Inject()(val metricFactory: MetricFactory,
@@ -58,9 +58,7 @@ class QuotaQueryMethod @Inject()(val metricFactory: MetricFactory,
       .map(invocationResult => InvocationWithContext(invocationResult, invocation.processingContext))
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[Exception, QuotaQueryRequest] =
-    QuotaSerializer.deserializeQuotaQueryRequest(invocation.arguments.value)
-      .asEither
-      .left.map(errors => new IllegalArgumentException(ResponseSerializer.serialize(JsError(errors)).toString))
+    QuotaSerializer.deserializeQuotaQueryRequest(invocation.arguments.value).asEitherRequest
 
   private def processRequest(mailboxSession: MailboxSession, invocation: Invocation, request: QuotaQueryRequest, capabilities: Set[CapabilityIdentifier]): SMono[Invocation] =
     jmapQuotaManagerWrapper.list(mailboxSession.getUser, capabilities)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala
index 998175f699..0266f05b45 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadChangesMethod.scala
@@ -23,12 +23,13 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{ErrorCode, Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{ResponseSerializer, ThreadSerializer}
+import org.apache.james.jmap.json.ThreadSerializer
 import org.apache.james.jmap.mail.{HasMoreChanges, ThreadChangesRequest, ThreadChangesResponse}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.MailboxSession
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.SMono
+
 import javax.inject.Inject
 
 class ThreadChangesMethod @Inject()(val metricFactory: MetricFactory,
@@ -60,6 +61,5 @@ class ThreadChangesMethod @Inject()(val metricFactory: MetricFactory,
     }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, ThreadChangesRequest] =
-    ThreadSerializer.deserializeChanges(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    ThreadSerializer.deserializeChanges(invocation.arguments.value).asEitherRequest
 }
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala
index b0069c940c..daee568bda 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/ThreadGetMethod.scala
@@ -23,7 +23,7 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE, JMAP_MAIL}
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.{AccountId, Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{ResponseSerializer, ThreadSerializer}
+import org.apache.james.jmap.json.ThreadSerializer
 import org.apache.james.jmap.mail.{Thread, ThreadGetRequest, ThreadGetResponse, ThreadNotFound, UnparsedThreadId}
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.mailbox.exception.ThreadNotFoundException
@@ -31,8 +31,8 @@ import org.apache.james.mailbox.model.{ThreadId => JavaThreadId}
 import org.apache.james.mailbox.{MailboxManager, MailboxSession}
 import org.apache.james.metrics.api.MetricFactory
 import reactor.core.scala.publisher.{SFlux, SMono}
-import javax.inject.Inject
 
+import javax.inject.Inject
 import scala.util.Try
 
 object ThreadGetResult {
@@ -78,8 +78,7 @@ class ThreadGetMethod @Inject()(val metricFactory: MetricFactory,
       .map(InvocationWithContext(_, invocation.processingContext))
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, ThreadGetRequest] =
-    ThreadSerializer.deserialize(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    ThreadSerializer.deserialize(invocation.arguments.value).asEitherRequest
 
   private def getThreadResponse(threadGetRequest: ThreadGetRequest,
                                 mailboxSession: MailboxSession): SFlux[ThreadGetResult] =
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala
index 246cb19ce2..a07c9384c8 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseGetMethod.scala
@@ -24,7 +24,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JM
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.UuidState.INSTANCE
 import org.apache.james.jmap.core.{AccountId, ErrorCode, Invocation, Properties, SessionTranslator}
-import org.apache.james.jmap.json.{ResponseSerializer, VacationSerializer}
+import org.apache.james.jmap.json.VacationSerializer
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.jmap.vacation.VacationResponse.UNPARSED_SINGLETON
 import org.apache.james.jmap.vacation.{UnparsedVacationResponseId, VacationResponse, VacationResponseGetRequest, VacationResponseGetResponse, VacationResponseNotFound}
@@ -83,9 +83,7 @@ class VacationResponseGetMethod @Inject()(vacationService: VacationService,
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, VacationResponseGetRequest] =
-    VacationSerializer.deserializeVacationResponseGetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
-
+    VacationSerializer.deserializeVacationResponseGetRequest(invocation.arguments.value).asEitherRequest
   private def getVacationResponse(vacationResponseGetRequest: VacationResponseGetRequest,
                                   mailboxSession: MailboxSession): SFlux[VacationResponseGetResult] =
     vacationResponseGetRequest.ids match {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala
index 0acfe169df..813938beaa 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/VacationResponseSetMethod.scala
@@ -29,7 +29,7 @@ import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JM
 import org.apache.james.jmap.core.Invocation.{Arguments, MethodName}
 import org.apache.james.jmap.core.SetError.SetErrorDescription
 import org.apache.james.jmap.core.{Invocation, SessionTranslator, UuidState}
-import org.apache.james.jmap.json.{ResponseSerializer, VacationSerializer}
+import org.apache.james.jmap.json.VacationSerializer
 import org.apache.james.jmap.method.VacationResponseSetMethod.VACATION_RESPONSE_PATCH_OBJECT_KEY
 import org.apache.james.jmap.routes.SessionSupplier
 import org.apache.james.jmap.vacation.{VacationResponseSetError, VacationResponseSetRequest, VacationResponseSetResponse, VacationResponseUpdateResponse}
@@ -38,6 +38,7 @@ import org.apache.james.metrics.api.MetricFactory
 import org.apache.james.vacation.api.{VacationPatch, VacationService, AccountId => VacationAccountId}
 import play.api.libs.json.JsObject
 import reactor.core.scala.publisher.{SFlux, SMono}
+
 import javax.inject.{Inject, Named}
 
 object VacationResponseUpdateResults {
@@ -97,8 +98,7 @@ class VacationResponseSetMethod @Inject()(@Named(InjectionKeys.JMAP) eventBus: E
   }
 
   override def getRequest(mailboxSession: MailboxSession, invocation: Invocation): Either[IllegalArgumentException, VacationResponseSetRequest] =
-    VacationSerializer.deserializeVacationResponseSetRequest(invocation.arguments.value)
-      .asEither.left.map(ResponseSerializer.asException)
+    VacationSerializer.deserializeVacationResponseSetRequest(invocation.arguments.value).asEitherRequest
 
   private def update(mailboxSession: MailboxSession, vacationResponseSetRequest: VacationResponseSetRequest): SMono[VacationResponseUpdateResults] = {
     SFlux.fromIterable(vacationResponseSetRequest.parsePatch()
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/package.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/package.scala
new file mode 100644
index 0000000000..1a11ad529f
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/package.scala
@@ -0,0 +1,48 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ * http://www.apache.org/licenses/LICENSE-2.0                   *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.jmap
+
+import org.apache.james.jmap.core.SetError
+import org.apache.james.jmap.core.SetError.SetErrorDescription
+import org.apache.james.jmap.json.ResponseSerializer
+import play.api.libs.json.{JsError, JsPath, JsResult, JsonValidationError}
+
+import scala.language.implicitConversions
+
+package object method {
+
+  def standardErrorMessage(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): String =
+    errors.head match {
+      case (path, Seq()) => s"'$path' property is not valid"
+      case (path, Seq(JsonValidationError(Seq("error.path.missing")))) => s"Missing '$path' property"
+      case (path, Seq(JsonValidationError(Seq("error.expected.jsarray")))) => s"'$path' property need to be an array"
+      case (path, Seq(JsonValidationError(Seq(message)))) => s"'$path' property is not valid: $message"
+      case (path, _) => s"Unknown error on property '$path'"
+      case _ => ResponseSerializer.serialize(JsError(errors)).toString()
+    }
+
+  def standardError(errors: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]): SetError =
+    SetError.invalidArguments(SetErrorDescription(standardErrorMessage(errors)))
+
+  implicit class AsEitherRequest[T](val jsResult: JsResult[T]) {
+    def asEitherRequest: Either[IllegalArgumentException, T] =
+      jsResult.asEither.left.map(errors => new IllegalArgumentException(standardErrorMessage(errors)))
+  }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org


[james-project] 02/02: Skip retry PropagateLookupRightListener when mailbox not found

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 6bceb0a2cc3f0a96bf9801f272382a4abb3db253
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Fri Jun 16 08:14:19 2023 +0700

    Skip retry PropagateLookupRightListener when mailbox not found
---
 .../org/apache/james/jmap/event/PropagateLookupRightListener.java    | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java
index 0d02571e19..1a53c515e9 100644
--- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java
+++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/event/PropagateLookupRightListener.java
@@ -35,6 +35,7 @@ import org.apache.james.mailbox.RightManager;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.events.MailboxEvents.MailboxACLUpdated;
 import org.apache.james.mailbox.events.MailboxEvents.MailboxRenamed;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.MailboxACL;
 import org.apache.james.mailbox.model.MailboxACL.Entry;
 import org.apache.james.mailbox.model.MailboxACL.Right;
@@ -95,6 +96,10 @@ public class PropagateLookupRightListener implements EventListener.ReactiveGroup
     private Mono<Void> updateLookupRightOnParent(MailboxRenamed mailboxRenamed) {
         MailboxSession mailboxSession = createMailboxSession(mailboxRenamed);
         return Mono.from(rightManager.listRightsReactive(mailboxRenamed.getNewPath(), mailboxSession))
+            .onErrorResume(MailboxNotFoundException.class, e -> {
+                LOGGER.info("Mailbox {} not found, skip lookup right update", mailboxRenamed.getNewPath());
+                return Mono.empty();
+            })
             .flatMapIterable(acl -> acl.getEntries().entrySet())
             .map(mapEntry -> new Entry(mapEntry.getKey(), mapEntry.getValue()))
             .filter(updateLookupRightPredicate())


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org