Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter logging to hide massive stacktrace for access issue #857

Merged
merged 1 commit into from
Jan 27, 2025

Conversation

amritghimire
Copy link
Contributor

@amritghimire amritghimire commented Jan 24, 2025

main > #856 > #857 (this)

With this change, we will return the ClientError without any extra error
or logs in the terminal. As a result, if we capture the ClientError in
the script, we will have minimum output.

Example query:

from datachain.error import ClientError
from datachain.lib.dc import C, DataChain

try:
    wds = (
        DataChain.from_storage("az://amrit-datachain-test/shards")
        .filter(C.name.glob("00000000.tar"))
        .settings(parallel=8, cache=True)
    )

    wds.show()
except ClientError as e:
    print(str(e))

print("Exception caught")

Before changes:

Traceback (most recent call last):                                                                                                                           
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/adlfs/spec.py", line 505, in do_connect
    raise ValueError(
ValueError: Must provide either a connection_string or account_name with credentials!!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/amritghimire/Documents/coding/iterative/datachain/test.py", line 12, in <module>
    DataChain.from_storage("az://amrit-datachain-test/shards")
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/dc.py", line 468, in from_storage
    .save(list_ds_name, listing=True)
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/dc.py", line 715, in save
    query=self._query.save(
          ^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/query/dataset.py", line 1637, in save
    query = self.apply_steps()
            ^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/query/dataset.py", line 1183, in apply_steps
    result = step.apply(
             ^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/query/dataset.py", line 598, in apply
    self.populate_udf_table(udf_table, query)
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/query/dataset.py", line 516, in populate_udf_table
    process_udf_outputs(
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/query/dataset.py", line 340, in process_udf_outputs
    for row in udf_output:
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/udf.py", line 463, in _process_row
    for result_obj in result_objs:
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/listing.py", line 36, in list_func
    for entries in iter_over_async(client.scandir(path.rstrip("/")), get_loop()):
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/asyn.py", line 280, in iter_over_async
    done, obj = asyncio.run_coroutine_threadsafe(get_next(), loop).result()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/.pyenv/versions/3.12.4/lib/python3.12/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/.pyenv/versions/3.12.4/lib/python3.12/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/asyn.py", line 273, in get_next
    obj = await ait.__anext__()
          ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/client/fsspec.py", line 249, in scandir
    await main_task
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/client/azure.py", line 50, in _fetch_flat
    async with self.fs.service_client.get_container_client(
               ^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/client/fsspec.py", line 201, in fs
    self._fs = self.create_fs(**self.fs_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/client/fsspec.py", line 136, in create_fs
    fs = cls.FS_CLASS(**kwargs)
         ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/fsspec/spec.py", line 81, in __call__
    obj = super().__call__(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/adlfs/spec.py", line 334, in __init__
    self.do_connect()
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/adlfs/spec.py", line 515, in do_connect
    raise ValueError(f"unable to connect to account for {e}")
ValueError: unable to connect to account for Must provide either a connection_string or account_name with credentials!!

After changes:

unable to connect to account for Must provide either a connection_string or account_name with credentials!!
Exception caught

Closes #600

Copy link

cloudflare-workers-and-pages bot commented Jan 24, 2025

Deploying datachain-documentation with  Cloudflare Pages  Cloudflare Pages

Latest commit: f0723bf
Status: ✅  Deploy successful!
Preview URL: https://96f452de.datachain-documentation.pages.dev
Branch Preview URL: https://amrit-filter-logging.datachain-documentation.pages.dev

View logs

@@ -23,6 +24,10 @@

D = TypeVar("D", bound="DataChain")

# Disable warnings for remote errors in clients
logging.getLogger("aiobotocore.credentials").setLevel(logging.CRITICAL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does logger settings affect stack traces?

@shcheklein
Copy link
Member

I think the idea is not swallow things, but probably wrap into more meaningful messages / exceptions when possible.

@amritghimire amritghimire self-assigned this Jan 24, 2025
@amritghimire
Copy link
Contributor Author

I think the idea is not swallow things, but probably wrap into more meaningful messages / exceptions when possible.

It doesn't swallow things but just disables the warnings or errors even when the exception has been raised for example :
https://github.com/fsspec/gcsfs/blob/81ffaccac7c92552fce7a629a9edc2bb3067d1b2/gcsfs/retry.py#L166-L167

As a result, even when we capture the exception, we had the stacktrace in the terminal output.
With this change, if we capture the ClientError, then we can handle the error ourselves without any output. If we don't handle the client error, still we will have complete the stacktrace.

Traceback (most recent call last):
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/listing.py", line 99, in _isfile
    info = client.fs.info(path)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/fsspec/asyn.py", line 118, in wrapper
    return sync(self.loop, func, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/fsspec/asyn.py", line 103, in sync
    raise return_result
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/fsspec/asyn.py", line 56, in _runner
    result[0] = await coro
                ^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/core.py", line 994, in _info
    exact = await self._get_object(path)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/core.py", line 527, in _get_object
    res = await self._call(
          ^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/core.py", line 447, in _call
    status, headers, info, contents = await self._request(
                                      ^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/decorator.py", line 221, in fun
    return await caller(func, *(extras + args), **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/retry.py", line 161, in retry_request
    raise e
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/retry.py", line 126, in retry_request
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/core.py", line 440, in _request
    validate_response(status, contents, path, args)
  File "/Users/amritghimire/Documents/coding/iterative/datachain/.venv/lib/python3.12/site-packages/gcsfs/retry.py", line 113, in validate_response
    raise HttpError(error)
gcsfs.retry.HttpError: Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission 'storage.objects.get' denied on resource (or it may not exist)., 401

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/amritghimire/Documents/coding/iterative/datachain/test.py", line 11, in <module>
    DataChain.from_storage("gs://amrit-datachain-test/shards")
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/dc.py", line 438, in from_storage
    list_ds_name, list_uri, list_path, list_ds_exists = get_listing(
                                                        ^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/listing.py", line 171, in get_listing
    ds_name, list_uri, list_path = parse_listing_uri(uri, cache, client_config)
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/listing.py", line 126, in parse_listing_uri
    if not uri.endswith("/") and _isfile(client, uri):
                                 ^^^^^^^^^^^^^^^^^^^^
  File "/Users/amritghimire/Documents/coding/iterative/datachain/src/datachain/lib/listing.py", line 111, in _isfile
    raise ClientError(
datachain.error.ClientError: Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission 'storage.objects.get' denied on resource (or it may not exist)., 401

As for the original ask in the issue #600 , we can also print the stacktrace to the debug logger and print one line output if we want.

Copy link

codecov bot commented Jan 24, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 87.59%. Comparing base (b1d4f2a) to head (f0723bf).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #857   +/-   ##
=======================================
  Coverage   87.59%   87.59%           
=======================================
  Files         128      128           
  Lines       11382    11385    +3     
  Branches     1540     1540           
=======================================
+ Hits         9970     9973    +3     
  Misses       1025     1025           
  Partials      387      387           
Flag Coverage Δ
datachain 87.52% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@shcheklein
Copy link
Member

@amritghimire okay, I see. thanks!

Base automatically changed from amrit/handle-permission-error-properly to main January 27, 2025 06:25
With this change, we will return the ClientError without any extra error
or logs in the terminal. As a result, if we capture the ClientError in
the script, we will have minimum output.

Example query:
```python
from datachain.error import ClientError
from datachain.lib.dc import C, DataChain

try:
    wds = (
        DataChain.from_storage("az://amrit-datachain-test/shards")
        .filter(C.name.glob("00000000.tar"))
        .settings(parallel=8, cache=True)
    )

    wds.show()
except ClientError as e:
    print(str(e))

print("Exception caught")
```

Closes #600
@amritghimire amritghimire merged commit ef23a20 into main Jan 27, 2025
37 checks passed
@amritghimire amritghimire deleted the amrit/filter-logging branch January 27, 2025 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error handling with bucket access issues
2 participants