Repository: praw-dev/praw

Issue:
KeyError on 400 request
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->

While trying to check the value of `/api/validate_submission_field`, I gave invalid request data (a missing field). I got a KeyError instead of the expected error.

**To Reproduce**
Steps to reproduce the behavior:
Run code: `r = reddit.post("/api/validate_submission_field", data={"sr": "AskReddit", "field": "link", "kind": "link", "title": "l", "text": "lol",  "show_error_list": True, })`

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
A `BadRequest ` is thrown.

**Code/Logs**
<!-- include your code, without the Reddit() initialization, so as to not leak private credentials. -->
```
---------------------------------------------------------------------------
BadRequest                                Traceback (most recent call last)
~/PycharmProjects/praw/praw/reddit.py in request(self, method, path, params, data, files)
    731                 params=params,
--> 732                 timeout=self.config.timeout,
    733             )

~/.virtualenvs/praw/venv/lib/python3.7/site-packages/prawcore/sessions.py in request(self, method, path, data, files, json, params, timeout)
    335             timeout=timeout,
--> 336             url=url,
    337         )

~/.virtualenvs/praw/venv/lib/python3.7/site-packages/prawcore/sessions.py in _request_with_retries(self, data, files, json, method, params, timeout, url, retry_strategy_state)
    264         elif response.status_code in self.STATUS_EXCEPTIONS:
--> 265             raise self.STATUS_EXCEPTIONS[response.status_code](response)
    266         elif response.status_code == codes["no_content"]:

BadRequest: received 400 HTTP response

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-5-e7b204c10e9b> in <module>
----> 1 r = reddit.post("/api/validate_submission_field", data={"sr": "AskReddit", "field": "link", "kind": "link", "title": "l", "text": "lol",  "show_error_list": True, })

~/PycharmProjects/praw/praw/reddit.py in post(self, path, data, files, params)
    635                 method="POST",
    636                 params=params,
--> 637                 path=path,
    638             )
    639         except RedditAPIException as exception:

~/PycharmProjects/praw/praw/reddit.py in _objectify_request(self, data, files, method, params, path)
    572         return self._objector.objectify(
    573             self.request(
--> 574                 data=data, files=files, method=method, params=params, path=path
    575             )
    576         )

~/PycharmProjects/praw/praw/reddit.py in request(self, method, path, params, data, files)
    748                 field = None
    749             raise RedditAPIException(
--> 750                 [data["reason"], data["explanation"], field]
    751             ) from exception
    752 

KeyError: 'reason'
```

**System Info**
 - OS: MacOS 10.14.6
 - Python: 3.7.7
 - PRAW Version: 7.0.0



Discussion:

Resolving patch:
diff --git a/praw/reddit.py b/praw/reddit.py
--- a/praw/reddit.py
+++ b/praw/reddit.py
@@ -778,6 +778,8 @@ def request(
                     "Unexpected BadRequest without json body. Please file a "
                     "bug at https://github.com/praw-dev/praw/issues"
                 ) from exception
+            if set(data) == {"error", "message"}:
+                raise
             if "fields" in data:
                 assert len(data["fields"]) == 1
                 field = data["fields"][0]


Test patch:
diff --git a/tests/integration/cassettes/TestReddit.test_bare_badrequest.json b/tests/integration/cassettes/TestReddit.test_bare_badrequest.json
new file mode 100644
--- /dev/null
+++ b/tests/integration/cassettes/TestReddit.test_bare_badrequest.json
@@ -0,0 +1,227 @@
+{
+  "http_interactions": [
+    {
+      "recorded_at": "2020-04-25T04:04:11",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "grant_type=password&password=<PASSWORD>&username=<USERNAME>"
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "Basic <BASIC_AUTH>"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "61"
+          ],
+          "Content-Type": [
+            "application/x-www-form-urlencoded"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.0.1.dev0 prawcore/1.3.0"
+          ]
+        },
+        "method": "POST",
+        "uri": "https://www.reddit.com/api/v1/access_token"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"access_token\": \"<ACCESS_TOKEN>\", \"token_type\": \"bearer\", \"expires_in\": 3600, \"scope\": \"*\"}"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "118"
+          ],
+          "Content-Type": [
+            "application/json; charset=UTF-8"
+          ],
+          "Date": [
+            "Sat, 25 Apr 2020 04:04:11 GMT"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "edgebucket=AnLAE7HXDx3vuCbfJT; Domain=reddit.com; Max-Age=63071999; Path=/;  secure"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=15552000; includeSubDomains; preload"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Cache": [
+            "MISS"
+          ],
+          "X-Cache-Hits": [
+            "0"
+          ],
+          "X-Moose": [
+            "majestic"
+          ],
+          "X-Served-By": [
+            "cache-lga21967-LGA"
+          ],
+          "X-Timer": [
+            "S1587787451.007135,VS0,VE313"
+          ],
+          "cache-control": [
+            "max-age=0, must-revalidate"
+          ],
+          "x-content-type-options": [
+            "nosniff"
+          ],
+          "x-frame-options": [
+            "SAMEORIGIN"
+          ],
+          "x-xss-protection": [
+            "1; mode=block"
+          ]
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://www.reddit.com/api/v1/access_token"
+      }
+    },
+    {
+      "recorded_at": "2020-04-25T04:04:11",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "api_type=json&field=link&kind=link&show_error_list=True&sr=AskReddit&text=lol&title=l"
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "bearer <ACCESS_TOKEN>"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "85"
+          ],
+          "Content-Type": [
+            "application/x-www-form-urlencoded"
+          ],
+          "Cookie": [
+            "edgebucket=AnLAE7HXDx3vuCbfJT"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.0.1.dev0 prawcore/1.3.0"
+          ]
+        },
+        "method": "POST",
+        "uri": "https://oauth.reddit.com/api/validate_submission_field?raw_json=1"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"message\": \"Bad Request\", \"error\": 400}"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "40"
+          ],
+          "Content-Type": [
+            "application/json; charset=UTF-8"
+          ],
+          "Date": [
+            "Sat, 25 Apr 2020 04:04:11 GMT"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=15552000; includeSubDomains; preload"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Cache": [
+            "MISS"
+          ],
+          "X-Cache-Hits": [
+            "0"
+          ],
+          "X-Moose": [
+            "majestic"
+          ],
+          "X-Served-By": [
+            "cache-lga21923-LGA"
+          ],
+          "X-Timer": [
+            "S1587787451.428813,VS0,VE91"
+          ],
+          "cache-control": [
+            "private, s-maxage=0, max-age=0, must-revalidate, no-store, max-age=0, must-revalidate"
+          ],
+          "expires": [
+            "-1"
+          ],
+          "set-cookie": [
+            "session_tracker=irJWpMk94h12lleHNU.0.1587787451480.Z0FBQUFBQmVvN2E3SHhuSjFlUGZlVjFXZE9TcFZJUnQ4S2Zrd3lRMHBQVTRlXzBnS1g3bUZqV3A1MWhEVFJVMEk0VFd3ejFKU1VuMUljTWhrUy1ZdmNvN1JTdUxqNEMwUWtIXzhaWHlDbnBKTkoyZ19pekgybUI4ZmttSHZfcE9iZzllaHhzbXQ2UTg; Domain=reddit.com; Max-Age=7199; Path=/; expires=Sat, 25-Apr-2020 06:04:11 GMT; secure",
+            "loid=00000000006at8zid4.2.1587787451513.Z0FBQUFBQmVvN2E3TXpaajhUSGFrTkVBRnZfUUFuVlI3NkJEYzdPcHI1LWJ0MVF3WTBRMWFTM2RDd2oybGloS0V1U01wTS1GLVFQN3BwR1hwWVFhVHRYeXZPc1FVd1RqT3hRR2RaMW5vX1JBbE0yOUxBN1J3aVE5MTV0RThvZU9fazdybzNJeG1CdnM; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Mon, 25-Apr-2022 04:04:11 GMT; secure",
+            "session_tracker=zr8WMkzRRNfy9OXsd8.0.1587787451513.Z0FBQUFBQmVvN2E3aHVrWjVyX2xBQVJ4V2JXUW5XNzZwbUN2UEpuVnllMVJwVzJJU2JKQkZTdV9xeTFSSXMwa25ldkFycDRySWQtb1NsaW5qaUJpWmNMb0lvVVQ5ZWJqRzV5SU9IenVuTFduX0tSb3BRZEZ2eGRkelVhalZiNDI3UUVuTTFkUTU2RnM; Domain=reddit.com; Max-Age=7199; Path=/; expires=Sat, 25-Apr-2020 06:04:11 GMT; secure"
+          ],
+          "x-content-type-options": [
+            "nosniff"
+          ],
+          "x-frame-options": [
+            "SAMEORIGIN"
+          ],
+          "x-ratelimit-remaining": [
+            "599.0"
+          ],
+          "x-ratelimit-reset": [
+            "349"
+          ],
+          "x-ratelimit-used": [
+            "1"
+          ],
+          "x-ua-compatible": [
+            "IE=edge"
+          ],
+          "x-xss-protection": [
+            "1; mode=block"
+          ]
+        },
+        "status": {
+          "code": 400,
+          "message": "Bad Request"
+        },
+        "url": "https://oauth.reddit.com/api/validate_submission_field?raw_json=1"
+      }
+    }
+  ],
+  "recorded_with": "betamax/0.8.1"
+}
diff --git a/tests/integration/test_reddit.py b/tests/integration/test_reddit.py
--- a/tests/integration/test_reddit.py
+++ b/tests/integration/test_reddit.py
@@ -1,14 +1,30 @@
 """Test praw.reddit."""
+import pytest
 from unittest import mock
 
 from praw.models import LiveThread
 from praw.models.reddit.base import RedditBase
 from praw.models.reddit.submission import Submission
+from prawcore.exceptions import BadRequest
 
 from . import IntegrationTest
 
 
 class TestReddit(IntegrationTest):
+    def test_bare_badrequest(self):
+        data = {
+            "sr": "AskReddit",
+            "field": "link",
+            "kind": "link",
+            "title": "l",
+            "text": "lol",
+            "show_error_list": True,
+        }
+        self.reddit.read_only = False
+        with self.recorder.use_cassette("TestReddit.test_bare_badrequest"):
+            with pytest.raises(BadRequest):
+                self.reddit.post("/api/validate_submission_field", data=data)
+
     def test_info(self):
         bases = ["t1_d7ltv", "t3_5dec", "t5_2qk"]
         items = []