Repository: dynaconf/dynaconf

Issue:
[bug] Duplicated text in ValidationError message
**Describe the bug**
There is a duplicated string in the string for a `ValidationError` message when using combined validators.

Logged output below includes some text from the error message, which is included in the reproducer
```
Configuration error in settings_file.yaml: combined validators failed combined validators failed EXAMPLE.username is required in env main or EXAMPLE.token is required in env main
```

The string `'combined validators failed'` is repeated during use of `str(ValidationError)`.


**To Reproduce**
Steps to reproduce the behavior:

```
settings = Dynaconf(settings_file='settings_file.yaml')

settings.validators.register(
    ((Validator("EXAMPLE.username", must_exist=True) & Validator("EXAMPLE.password", must_exist=True))
    | Validator("EXAMPLE.token", must_exist=True))
)

try:
    settings.validators.validate()
except ValidationError as err:
    print(f"Configuration error in settings_file.yaml: {err}")
```

<!-- Describe or use the command `$ tree -v` and paste below -->

I don't think the folder structure is relevant to the bug, but the use within a project can be seen here:
https://github.com/SatelliteQE/broker/pull/38

2. Having the following config files:

<!-- Please adjust if you are using different files and formats! -->

<details>
<summary> Config files </summary>

**settings_file.yaml**
```yaml
EXAMPLE:
    username: tester
    # missing password or token
```

</details>


**Expected behavior**
The `ValidationError` exception message only includes the statement `'combined validators failed'` once.

**Environment (please complete the following information):**
 - OS: Fedora 30
 - Dynaconf Version 3.1.0


[bug] Duplicated text in ValidationError message
**Describe the bug**
There is a duplicated string in the string for a `ValidationError` message when using combined validators.

Logged output below includes some text from the error message, which is included in the reproducer
```
Configuration error in settings_file.yaml: combined validators failed combined validators failed EXAMPLE.username is required in env main or EXAMPLE.token is required in env main
```

The string `'combined validators failed'` is repeated during use of `str(ValidationError)`.


**To Reproduce**
Steps to reproduce the behavior:

```
settings = Dynaconf(settings_file='settings_file.yaml')

settings.validators.register(
    ((Validator("EXAMPLE.username", must_exist=True) & Validator("EXAMPLE.password", must_exist=True))
    | Validator("EXAMPLE.token", must_exist=True))
)

try:
    settings.validators.validate()
except ValidationError as err:
    print(f"Configuration error in settings_file.yaml: {err}")
```

<!-- Describe or use the command `$ tree -v` and paste below -->

I don't think the folder structure is relevant to the bug, but the use within a project can be seen here:
https://github.com/SatelliteQE/broker/pull/38

2. Having the following config files:

<!-- Please adjust if you are using different files and formats! -->

<details>
<summary> Config files </summary>

**settings_file.yaml**
```yaml
EXAMPLE:
    username: tester
    # missing password or token
```

</details>


**Expected behavior**
The `ValidationError` exception message only includes the statement `'combined validators failed'` once.

**Environment (please complete the following information):**
 - OS: Fedora 30
 - Dynaconf Version 3.1.0




Discussion:

Resolving patch:
diff --git a/dynaconf/validator.py b/dynaconf/validator.py
--- a/dynaconf/validator.py
+++ b/dynaconf/validator.py
@@ -262,9 +262,13 @@ def validate(self, settings):
                 continue
             else:
                 return
+
         raise ValidationError(
             self.messages["combined"].format(
-                errors=" or ".join(str(e) for e in errors)
+                errors=" or ".join(
+                    str(e).replace("combined validators failed ", "")
+                    for e in errors
+                )
             )
         )
 
@@ -281,10 +285,14 @@ def validate(self, settings):
             except ValidationError as e:
                 errors.append(e)
                 continue
+
         if errors:
             raise ValidationError(
                 self.messages["combined"].format(
-                    errors=" and ".join(str(e) for e in errors)
+                    errors=" and ".join(
+                        str(e).replace("combined validators failed ", "")
+                        for e in errors
+                    )
                 )
             )
 
diff --git a/example/issues/404_dup_validator_message/app.py b/example/issues/404_dup_validator_message/app.py
new file mode 100644
--- /dev/null
+++ b/example/issues/404_dup_validator_message/app.py
@@ -0,0 +1,44 @@
+from dynaconf import Dynaconf
+from dynaconf import ValidationError
+from dynaconf import Validator
+
+settings = Dynaconf(settings_file="settings_file.yaml")
+
+settings.validators.register(
+    (
+        Validator("EXAMPLE.username", must_exist=True)
+        & Validator("EXAMPLE.password", must_exist=True)
+    )
+    | Validator("EXAMPLE.token", must_exist=True)
+)
+
+try:
+    settings.validators.validate()
+except ValidationError as err:
+    assert (
+        str(err)
+        == "combined validators failed EXAMPLE.username is required in env"
+        " main and EXAMPLE.password is required in env main or EXAMPLE.token"
+        " is required in env main"
+    ), str(err)
+
+
+settings = Dynaconf(settings_file="settings_file.yaml")
+
+settings.validators.register(
+    (
+        Validator("EXAMPLE.username", must_exist=True)
+        | Validator("EXAMPLE.password", must_exist=True)
+    )
+    | Validator("EXAMPLE.token", must_exist=True)
+)
+
+try:
+    settings.validators.validate()
+except ValidationError as err:
+    assert (
+        str(err)
+        == "combined validators failed EXAMPLE.username is required in env"
+        " main or EXAMPLE.password is required in env main or EXAMPLE.token is"
+        " required in env main"
+    ), str(err)


Test patch: