Repository: litestar-org/litestar

Issue:
Enhancement: Add a way to override default OpenAPI response descriptions
**What's the feature you'd like to ask for.**
Currently there is no way to replace the default OpenAPI description for HTTP 400 errors. For example, you currently can't do this:

```python
@starlite.post(
    "/path",
    responses={
        400: starlite.ResponseSpec(
            model=MyErrorModel, description="A more detailed error description"
        )
    },
)
async def login() -> starlite.Response:
    ...
```

If you do, you will get this error on startup:

```console
starlite.exceptions.http_exceptions.ImproperlyConfiguredException: 500: Additional response for status code 400 already exists in success or error responses
```

This makes it impossible to add more detailed error descriptions or properly document response shapes if you want your endpoint to return a different error shape.

**Additional context**
Removing this bit of code would allow the default HTTP 400 description to be replaced:
https://github.com/seladb/starlite/blob/51ae7eebda3e6834a6520471bfdb9cad2ab790c5/starlite/openapi/responses.py#L217-L220



Discussion:
Have you tried using the raises key? 
The raises key doesn't let you specify a model, just an exception type, so you can't specify any OpenAPI details.
Ok, i understand the issue.

Would you like to submit a PR?
> Ok, i understand the issue.
> 
> Would you like to submit a PR?

Yeah can do, I'll get one up tonight.

Resolving patch:
diff --git a/starlite/_openapi/responses.py b/starlite/_openapi/responses.py
--- a/starlite/_openapi/responses.py
+++ b/starlite/_openapi/responses.py
@@ -14,7 +14,7 @@
 from starlite._openapi.utils import pascal_case_to_text
 from starlite._signature.models import SignatureField
 from starlite.enums import MediaType
-from starlite.exceptions import HTTPException, ImproperlyConfiguredException, ValidationException
+from starlite.exceptions import HTTPException, ValidationException
 from starlite.response import Response as StarliteResponse
 from starlite.response_containers import File, Redirect, Stream, Template
 from starlite.utils import get_enum_string_value, get_name, is_class_and_subclass
@@ -235,11 +235,6 @@ def create_responses(
         responses[status_code] = response
 
     for status_code, response in create_additional_responses(route_handler, plugins):
-        if status_code in responses:
-            raise ImproperlyConfiguredException(
-                f"Additional response for status code {status_code} already exists in success or error responses"
-            )
-
         responses[status_code] = response
 
     return responses or None


Test patch:
diff --git a/tests/openapi/test_responses.py b/tests/openapi/test_responses.py
--- a/tests/openapi/test_responses.py
+++ b/tests/openapi/test_responses.py
@@ -16,7 +16,6 @@
 from starlite.datastructures import Cookie, ResponseHeader
 from starlite.exceptions import (
     HTTPException,
-    ImproperlyConfiguredException,
     PermissionDeniedException,
     ValidationException,
 )
@@ -249,15 +248,33 @@ def test_additional_responses_overlap_with_other_responses() -> None:
     class OkResponse(BaseModel):
         pass
 
-    @get(responses={200: ResponseSpec(model=OkResponse)})
+    @get(responses={200: ResponseSpec(model=OkResponse, description="Overwritten response")})
     def handler() -> Person:
         return PersonFactory.build()
 
-    with pytest.raises(
-        ImproperlyConfiguredException,
-        match="Additional response for status code 200 already exists in success or error responses",
-    ):
-        create_responses(handler, raises_validation_error=True, generate_examples=False, plugins=[])
+    responses = create_responses(handler, raises_validation_error=True, generate_examples=False, plugins=[])
+
+    assert responses is not None
+    assert responses["200"] is not None
+    assert responses["200"].description == "Overwritten response"
+
+
+def test_additional_responses_overlap_with_raises() -> None:
+    class ErrorResponse(BaseModel):
+        pass
+
+    @get(
+        raises=[ValidationException],
+        responses={400: ResponseSpec(model=ErrorResponse, description="Overwritten response")},
+    )
+    def handler() -> Person:
+        raise ValidationException()
+
+    responses = create_responses(handler, raises_validation_error=True, generate_examples=False, plugins=[])
+
+    assert responses is not None
+    assert responses["400"] is not None
+    assert responses["400"].description == "Overwritten response"
 
 
 def test_create_response_for_response_subclass() -> None: