mlco2 / codecarbon

Track emissions from Compute and recommend ways to reduce their impact on the environment.
https://mlco2.github.io/codecarbon
MIT License
1.01k stars 158 forks source link

Better error message on invalid inputs #480

Closed Erotemic closed 7 months ago

Erotemic commented 7 months ago

I was getting an error when running this code:

    from codecarbon import OfflineEmissionsTracker
    emissions_tracker = OfflineEmissionsTracker(
        country_iso_code='USA',
        region='Virginia',
        cloud_provider='aws',
        cloud_region='us-east-1',
        country_2letter_iso_code='us'
    )

    emissions_tracker.start()
    emissions_tracker.flush()

I think it is because of a misconfiguration, removing everything but the country_iso_code seems to work, but I thought the error I ran into (about a length-0 data frame) was cryptic, so I checked for a failure and raised a better message.

Erotemic commented 7 months ago

I've added a similar error checking mechanism in the other 2 places where this error might occur.

I'm not sure how to best integrate with the existing patterns. It looks like logger.error is used basically everywhere, and all exceptions just seem to be logged and then the code is allowed to continue. Unlike in those cases there (currently) isn't any fallback for when this information isn't available. So I just raised a ValueError. It's at least better than the current behavior where the error message looks like:

[codecarbon WARNING @ 13:43:09] graceful shutdown. Exceptions:
[codecarbon WARNING @ 13:43:09] <class 'Exception'>
Traceback (most recent call last):
  File "/home/joncrall/code/codecarbon/codecarbon/core/util.py", line 18, in suppress
    yield
  File "/home/joncrall/.pyenv/versions/3.11.2/lib/python3.11/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/code/codecarbon/codecarbon/emissions_tracker.py", line 498, in flush
    emissions_data = self._prepare_emissions_data()
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/code/codecarbon/codecarbon/emissions_tracker.py", line 570, in _prepare_emissions_data
    country_name = self._emissions.get_cloud_country_name(cloud)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/code/codecarbon/codecarbon/core/emissions.py", line 83, in get_cloud_country_name
    return selected["country_name"].item()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/.pyenv/versions/3.11.2/envs/pyenv3.11.2/lib/python3.11/site-packages/pandas/core/base.py", line 347, in item
    raise ValueError("can only convert an array of size 1 to a Python scalar")

The new exception looks like this:

[codecarbon WARNING @ 13:43:31] graceful shutdown. Exceptions:
[codecarbon WARNING @ 13:43:31] <class 'Exception'>
Traceback (most recent call last):
  File "/home/joncrall/code/codecarbon/codecarbon/core/util.py", line 18, in suppress
    yield
  File "/home/joncrall/.pyenv/versions/3.11.2/lib/python3.11/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/code/codecarbon/codecarbon/emissions_tracker.py", line 498, in flush
    emissions_data = self._prepare_emissions_data()
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/code/codecarbon/codecarbon/emissions_tracker.py", line 570, in _prepare_emissions_data
    country_name = self._emissions.get_cloud_country_name(cloud)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/joncrall/code/codecarbon/codecarbon/core/emissions.py", line 77, in get_cloud_country_name
    raise ValueError(
ValueError: Unable to find country name for cloud_provider=aws, cloud_region=us-east-1

I've also added tests for these errors. Not sure if that's necessary (or if they are in the right place).

Please advise on any changes necessary to help this PR land.