Fix the following error in unit tests:
```
AttributeError: 'TestToolShedConfig' object has no attribute 'hgweb_repo_prefix'
```
caused by merging commit b00beec3d2
forward.
Fixes https://sentry.galaxyproject.org/share/issue/026b0ea1f8aa478daea1cdb0b18df78a/:
```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
File "starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "starlette/middleware/errors.py", line 186, in __call__
raise exc
File "starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "starlette_context/middleware/raw_middleware.py", line 92, in __call__
await self.app(scope, receive, send_wrapper)
File "starlette/middleware/base.py", line 189, in __call__
with collapse_excgroups():
File "contextlib.py", line 155, in __exit__
self.gen.throw(typ, value, traceback)
File "starlette/_utils.py", line 93, in collapse_excgroups
raise exc
File "starlette/middleware/base.py", line 191, in __call__
response = await self.dispatch_func(request, call_next)
File "galaxy/webapps/galaxy/fast_app.py", line 109, in add_x_frame_options
response = await call_next(request)
File "starlette/middleware/base.py", line 165, in call_next
raise app_exc
File "starlette/middleware/base.py", line 151, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "starlette/middleware/exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "starlette/routing.py", line 758, in __call__
await self.middleware_stack(scope, receive, send)
File "starlette/routing.py", line 778, in app
await route.handle(scope, receive, send)
File "starlette/routing.py", line 299, in handle
await self.app(scope, receive, send)
File "starlette/routing.py", line 79, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "starlette/routing.py", line 74, in app
response = await func(request)
File "fastapi/routing.py", line 278, in app
raw_response = await run_endpoint_function(
File "fastapi/routing.py", line 193, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "starlette/concurrency.py", line 42, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "anyio/to_thread.py", line 56, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
File "anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
return await future
File "anyio/_backends/_asyncio.py", line 851, in run
result = context.run(func, *args)
File "galaxy/webapps/galaxy/api/datasets.py", line 446, in show
return self.service.show(trans, dataset_id, hda_ldda, serialization_params, data_type, **extra_params)
File "galaxy/webapps/galaxy/services/datasets.py", line 395, in show
rval = self._raw_data(trans, dataset, **extra_params)
File "galaxy/webapps/galaxy/services/datasets.py", line 1009, in _raw_data
return DataResult(data=list(dataset.datatype.dataprovider(dataset, provider, **kwargs)))
File "galaxy/datatypes/dataproviders/base.py", line 262, in __iter__
for datum in parent_gen:
File "galaxy/datatypes/dataproviders/base.py", line 199, in __iter__
for datum in parent_gen:
File "galaxy/datatypes/dataproviders/base.py", line 137, in __iter__
yield from self.source
File "galaxy/datatypes/dataproviders/base.py", line 137, in __iter__
yield from self.source
File "<frozen codecs>", line 322, in decode
```
Fixes
https://sentry.galaxyproject.org/share/issue/cde32ad8b3cc4d58a519743a90e0d9a3/:
```
FileNotFoundError: [Errno 2] No such file or directory: ''
File "starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "starlette/middleware/errors.py", line 186, in __call__
raise exc
File "starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "starlette_context/middleware/raw_middleware.py", line 92, in __call__
await self.app(scope, receive, send_wrapper)
File "starlette/middleware/base.py", line 189, in __call__
with collapse_excgroups():
File "contextlib.py", line 155, in __exit__
self.gen.throw(typ, value, traceback)
File "starlette/_utils.py", line 93, in collapse_excgroups
raise exc
File "starlette/middleware/base.py", line 191, in __call__
response = await self.dispatch_func(request, call_next)
File "galaxy/webapps/galaxy/fast_app.py", line 109, in add_x_frame_options
response = await call_next(request)
File "starlette/middleware/base.py", line 165, in call_next
raise app_exc
File "starlette/middleware/base.py", line 151, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "starlette/middleware/exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "starlette/routing.py", line 758, in __call__
await self.middleware_stack(scope, receive, send)
File "starlette/routing.py", line 778, in app
await route.handle(scope, receive, send)
File "starlette/routing.py", line 299, in handle
await self.app(scope, receive, send)
File "starlette/routing.py", line 79, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "starlette/routing.py", line 74, in app
response = await func(request)
File "fastapi/routing.py", line 278, in app
raw_response = await run_endpoint_function(
File "fastapi/routing.py", line 193, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "starlette/concurrency.py", line 42, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "anyio/to_thread.py", line 56, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
File "anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
return await future
File "anyio/_backends/_asyncio.py", line 851, in run
result = context.run(func, *args)
File "galaxy/webapps/galaxy/api/history_contents.py", line 646, in download_dataset_collection
return self._download_collection(trans, id)
File "galaxy/webapps/galaxy/api/history_contents.py", line 1036, in _download_collection
archive = self.service.get_dataset_collection_archive_for_download(trans, id)
File "galaxy/webapps/galaxy/services/history_contents.py", line 479, in get_dataset_collection_archive_for_download
return self.__stream_dataset_collection(trans, dataset_collection_instance)
File "galaxy/webapps/galaxy/services/history_contents.py", line 498, in __stream_dataset_collection
archive = hdcas.stream_dataset_collection(
File "galaxy/managers/hdcas.py", line 39, in stream_dataset_collection
write_dataset_collection(dataset_collection_instance, archive)
File "galaxy/managers/hdcas.py", line 51, in write_dataset_collection
archive.write(file_path, relpath)
File "galaxy/util/zipstream.py", line 82, in write
self.add_path(path, archive_name or os.path.basename(path))
File "galaxy/util/zipstream.py", line 52, in add_path
size = int(os.stat(path).st_size)
```
If we can't look up the directory it's safe to assume it really is gone.
Fixes `None delete error [Errno 39] Directory not empty:
'outputs_populated'`.
This prevents `ProtocolError` caused by the error middleware not being
able to reset the content length. Only affects routes that explicitly
set the content-length and don't have a default response handler.
This is effectively the case when using `web.expose`. To test this,
make sure you get Galaxy's error middleware output in the browser
and your console.
```
diff --git a/lib/galaxy/webapps/galaxy/controllers/dataset.py b/lib/galaxy/webapps/galaxy/controllers/dataset.py
index c95d9df788..92b04684d3 100644
--- a/lib/galaxy/webapps/galaxy/controllers/dataset.py
+++ b/lib/galaxy/webapps/galaxy/controllers/dataset.py
@@ -456,6 +456,8 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
def imp(self, trans, dataset_id=None, **kwd):
"""Import another user's dataset via a shared URL; dataset is added to user's current history."""
# Set referer message.
+ trans.response.headers["content-length"] = 0
+ trans = None
referer = trans.request.referer
if referer and not referer.startswith(f"{trans.request.application_url}{url_for('/login')}"):
referer_message = f"<a href='{escape(referer)}'>return to the previous page</a>"
```