Repository: dmwm/wmcore
Issue: KeyError exception in RequestDBReader module

**Impact of the bug**
ReqMgr2

**Describe the bug**
This issue has actually being addressed in: https://github.com/dmwm/WMCore/pull/11001
but given that it's not related to the CouchDB upgrade, I decided to separate it in its own ticket.

If we need to fetch details for a given workflow from CouchDB reqmgr database and it fails to fetch that information - or an inexistent request is provided - it hits a KeyError exception when parsing the output from the couchdb query. So, we should first check whether any non-empty results came back before parsing it.

**How to reproduce it**
https://cmsweb-testbed.cern.ch/reqmgr2/data/request?name=blah

**Expected behavior**
Instead of raising an exception, we should simply return an empty result.

**Additional context and error message**
Traeceback on the server side:
```
[24/May/2022:20:44:06]  SERVER OTHER ERROR __builtins__.KeyError 9f55bc1e1a84aa2cf274098e2ad5c4ce ('RequestName')
[24/May/2022:20:44:06]    Traceback (most recent call last):
[24/May/2022:20:44:06]      File "/data/srv/HG2205e/sw/slc7_amd64_gcc630/cms/reqmgr2/2.0.3.pre7/lib/python3.8/site-packages/WMCore/REST/Server.py", line 728, in default
[24/May/2022:20:44:06]        return self._call(RESTArgs(list(args), kwargs))
[24/May/2022:20:44:06]      File "/data/srv/HG2205e/sw/slc7_amd64_gcc630/cms/reqmgr2/2.0.3.pre7/lib/python3.8/site-packages/WMCore/REST/Server.py", line 809, in _call
[24/May/2022:20:44:06]        obj = apiobj['call'](*safe.args, **safe.kwargs)
[24/May/2022:20:44:06]      File "/data/srv/HG2205e/sw/slc7_amd64_gcc630/cms/reqmgr2/2.0.3.pre7/lib/python3.8/site-packages/WMCore/ReqMgr/Service/Request.py", line 317, in get
[24/May/2022:20:44:06]        request_info.append(self.reqmgr_db_service.getRequestByNames(name))
[24/May/2022:20:44:06]      File "/data/srv/HG2205e/sw/slc7_amd64_gcc630/cms/reqmgr2/2.0.3.pre7/lib/python3.8/site-packages/WMCore/Services/RequestDB/RequestDBReader.py", line 170, in getRequestByNames
[24/May/2022:20:44:06]        requestInfo = self._getRequestByName(requestNames, detail=detail)
[24/May/2022:20:44:06]      File "/data/srv/HG2205e/sw/slc7_amd64_gcc630/cms/reqmgr2/2.0.3.pre7/lib/python3.8/site-packages/WMCore/Services/RequestDB/RequestDBReader.py", line 80, in _getRequestByName
[24/May/2022:20:44:06]        result = {result['RequestName']: result}
[24/May/2022:20:44:06]    KeyError: 'RequestName'
[24/May/2022:20:44:06] reqmgr2-66cf5d8bfc-mw6x8 xxxx "GET /reqmgr2/data/request?name=blah HTTP/1.1" 500 Internal Server Error 
```

Changed files:
src/python/WMCore/Services/RequestDB/RequestDBReader.py

diff --git a/src/python/WMCore/Services/RequestDB/RequestDBReader.py b/src/python/WMCore/Services/RequestDB/RequestDBReader.py
index a0e7d20e8..c8cdef032 100644
--- a/src/python/WMCore/Services/RequestDB/RequestDBReader.py
+++ b/src/python/WMCore/Services/RequestDB/RequestDBReader.py
@@ -73,14 +73,24 @@ class RequestDBReader(object):
             return list(result)
 
     def _getRequestByName(self, requestName, detail):
+        """
+        Retrieves a request dictionary from CouchDB
+        :param requestName: string with the request name
+        :param detail: boolean with False value for retrieving only the
+            workflow name, or True for retrieving all its description
+        :return: a list with the request name. Or a dictionary with the
+            request description if detail=true
+        """
+        # this returns a dictionary with the workflow description, or
+        # an empty dictionary if nothing is found in CouchDB
         result = self.couchDB.getDoc(requestName)
+        if not result:
+            return dict()
         if detail:
             result.pop('_attachments', None)
             result.pop('_rev', None)
-            result = {result['RequestName']: result}
-        else:
-            result = [result['RequestName']]
-        return result
+            return {result['RequestName']: result}
+        return [result['RequestName']]
 
     def _getRequestByNames(self, requestNames, detail):
         """