Repository: rucio/rucio
Issue: Client raising the wrong error

Motivation
----------

From Stephane:

> when I introduce a typo in the RSE name, the error message which I expect 'RSE does not exist' is very complicated : 
> 
> ```
> -bash-4.1$ rucio -v download --rse MWt2_DATADISK mc16_13TeV:HITS.17430965._017098.pool.root.1
> 2019-03-26 10:12:16,014 INFO    Processing 1 item(s) for input
> 2019-03-26 10:12:16,014 DEBUG   Processing item mc16_13TeV:HITS.17430965._017098.pool.root.1
> 2019-03-26 10:12:16,015 DEBUG   RSE-Expression: (MWt2_DATADISK)&istape=False
> 2019-03-26 10:12:16,015 DEBUG   Splitted DID: mc16_13TeV:HITS.17430965._017098.pool.root.1
> 2019-03-26 10:12:16,055 DEBUG   1 DIDs after processing input
> 2019-03-26 10:12:16,056 DEBUG   Processing: {'resolve_archives': True, 'name': 'HITS.17430965._017098.pool.root.1', 'did': 'mc16_13TeV:HITS.17430965._017098.pool.root.1', 'rse': '(MWt2_DATADISK)&istape=False', 'no_subdir': False, 'nrandom': None, 'transfer_timeout': 3600, 'scope': 'mc16_13TeV', 'type': u'FILE', 'force_scheme': None, 'base_dir': '.'}
> 2019-03-26 10:12:16,080 DEBUG   <?xml version="1.0" encoding="UTF-8"?>
> <metalink xmlns="urn:ietf:params:xml:ns:metalink">
> 
> 2019-03-26 10:12:16,092 DEBUG   Traceback (most recent call last):
>   File "/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/rucio-clients/1.18.5/bin/rucio", line 159, in new_funct
>     return function(*args, **kwargs)
>   File "/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/rucio-clients/1.18.5/bin/rucio", line 968, in download
>     result = download_client.download_dids(items, args.ndownloader, trace_pattern)
>   File "/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/rucio-clients/1.18.5/lib/python2.7/site-packages/rucio/client/downloadclient.py", line 291, in download_dids
>     input_items = self._prepare_items_for_download(items)
>   File "/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/rucio-clients/1.18.5/lib/python2.7/site-packages/rucio/client/downloadclient.py", line 914, in _prepare_items_for_download
>     files_with_pfns = self._parse_list_replica_metalink(metalink_str)
>   File "/cvmfs/atlas.cern.ch/repo/ATLASLocalRootBase/x86_64/rucio-clients/1.18.5/lib/python2.7/site-packages/rucio/client/downloadclient.py", line 996, in _parse_list_replica_metalink
>     raise error
> ExpatError: no element found: line 3, column 0
> 
> 2019-03-26 10:12:16,092 ERROR   no element found: line 3, column 0
> 2019-03-26 10:12:16,093 ERROR   Strange error: No section: 'policy' ```

This should raise `RSENotFound`.

Changed files:
lib/rucio/web/rest/webpy/v1/replica.py

diff --git a/lib/rucio/web/rest/webpy/v1/replica.py b/lib/rucio/web/rest/webpy/v1/replica.py
index 65f2f7fac..74637fd7e 100755
--- a/lib/rucio/web/rest/webpy/v1/replica.py
+++ b/lib/rucio/web/rest/webpy/v1/replica.py
@@ -112,15 +112,23 @@ class Replicas(RucioController):
             schemes = supported_protocols
 
         try:
-            # first, set the appropriate content type, and stream the header
-            if not metalink:
-                header('Content-Type', 'application/x-json-stream')
-            else:
-                header('Content-Type', 'application/metalink4+xml')
-                yield '<?xml version="1.0" encoding="UTF-8"?>\\n<metalink xmlns="urn:ietf:params:xml:ns:metalink">\\n'
+
+            # we need to call list_replicas before starting to reply
+            # otherwise the exceptions won't be propagated correctly
+            __first = True
 
             # then, stream the replica information
             for rfile in list_replicas(dids=dids, schemes=schemes):
+
+                # in first round, set the appropriate content type, and stream the header
+                if __first:
+                    if not metalink:
+                        header('Content-Type', 'application/x-json-stream')
+                    else:
+                        header('Content-Type', 'application/metalink4+xml')
+                        yield '<?xml version="1.0" encoding="UTF-8"?>\\n<metalink xmlns="urn:ietf:params:xml:ns:metalink">\\n'
+                    __first = False
+
                 client_ip = ctx.env.get('HTTP_X_FORWARDED_FOR')
                 if client_ip is None:
                     client_ip = ctx.ip
@@ -359,12 +367,10 @@ class ListReplicas(RucioController):
             schemes = supported_protocols
 
         try:
-            # first, set the appropriate content type, and stream the header
-            if not metalink:
-                header('Content-Type', 'application/x-json-stream')
-            else:
-                header('Content-Type', 'application/metalink4+xml')
-                yield '<?xml version="1.0" encoding="UTF-8"?>\\n<metalink xmlns="urn:ietf:params:xml:ns:metalink">\\n'
+
+            # we need to call list_replicas before starting to reply
+            # otherwise the exceptions won't be propagated correctly
+            __first = True
 
             # then, stream the replica information
             for rfile in list_replicas(dids=dids, schemes=schemes,
@@ -378,6 +384,16 @@ class ListReplicas(RucioController):
                                        resolve_archives=resolve_archives,
                                        resolve_parents=resolve_parents,
                                        issuer=ctx.env.get('issuer')):
+
+                # in first round, set the appropriate content type, and stream the header
+                if __first:
+                    if not metalink:
+                        header('Content-Type', 'application/x-json-stream')
+                    else:
+                        header('Content-Type', 'application/metalink4+xml')
+                        yield '<?xml version="1.0" encoding="UTF-8"?>\\n<metalink xmlns="urn:ietf:params:xml:ns:metalink">\\n'
+                    __first = False
+
                 if not metalink:
                     yield dumps(rfile, cls=APIEncoder) + '\\n'
                 else: