Skip to content

logging library doesn't support Exceptions #172

Description

@sjudd

The logger in firebase_functions doesn't seem to provide reasonable support for exceptions.

In the example, firebase suggests extracting a portion of the error and including it:

try
...
except:
    e = sys.exc_info()[0]
    # Attach an error object as the second argument
    logger.error("Unable to read quote from Firestore, sending default instead", error=e)

However this fails with an error:

../../../../Library/Caches/pypoetry/virtualenvs/oasis-zYbk3Ww0-py3.11/lib/python3.11/site-packages/firebase_functions/logger.py:130: in error
    write(_entry_from_args(LogSeverity.ERROR, *args, **kwargs))
../../../../Library/Caches/pypoetry/virtualenvs/oasis-zYbk3Ww0-py3.11/lib/python3.11/site-packages/firebase_functions/logger.py:95: in write
    print(_json.dumps(_remove_circular(entry)), file=write_file)
../../../../.pyenv/versions/3.11.7/lib/python3.11/json/__init__.py:231: in dumps
    return _default_encoder.encode(obj)
../../../../.pyenv/versions/3.11.7/lib/python3.11/json/encoder.py:200: in encode
    chunks = self.iterencode(o, _one_shot=True)
../../../../.pyenv/versions/3.11.7/lib/python3.11/json/encoder.py:258: in iterencode
    return _iterencode(o, 0)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <json.encoder.JSONEncoder object at 0x10166ee10>, o = <class 'TypeError'>

    def default(self, o):
        """Implement this method in a subclass such that it returns
        a serializable object for ``o``, or calls the base implementation
        (to raise a ``TypeError``).
    
        For example, to support arbitrary iterators, you could
        implement default like this::
    
            def default(self, o):
                try:
                    iterable = iter(o)
                except TypeError:
                    pass
                else:
                    return list(iterable)
                # Let the base class default method raise the TypeError
                return JSONEncoder.default(self, o)
    
        """
>       raise TypeError(f'Object of type {o.__class__.__name__} '
                        f'is not JSON serializable')
E       TypeError: Object of type type is not JSON serializable

../../../../.pyenv/versions/3.11.7/lib/python3.11/json/encoder.py:180: TypeError

Moreover it's not really an ideal API to log a subset of an exception. Ideally the entire stack trace would be included.

If you instead simply print the error, you can see a reasonable stack trace in the logs for the function.

I'd expect the example to not throw. I'd also expect the logging API to explicitly support logging Exceptions with stack traces

Activity

  1. mattprinold commented on Mar 1, 2024

    @mattprinold

    so i ran into this problem also. It seems that the logger is trying to serialize an exception which is not possible so you need to convert the exception to something that is serializable, like a string representation of the exception. Found this out thanks to this stackoverflow thread: https://stackoverflow.com/questions/68108446/typeerror-object-of-type-typeerror-is-not-json-serializable-python

    This should resolve the problem:
    logger.error("Unable to read quote from Firestore, sending default instead", error=str(e))

    You also shouldn't be using a bare except so for a better message use something like:

    except Exception as e:
        logger.error("Unable to read quote from Firestore, sending default instead", error=str(e))
    
  2. moved this from Needs Acknowledgment to backlog in [Cloud] Extensions + Functionson Jun 5, 2025
  3. HassanBahati commented on Dec 8, 2025

    @HassanBahati
    Contributor

    Hi @sjudd, thank you for reporting this issue. We have received it and we shall keep you posted on any developments. Cheers!

  4. cabljac commented on Jul 22, 2026

    @cabljac
    Contributor

    Going through the backlog of open issues. Confirmed the shape of this one: logger.error(..., error=e) hits TypeError: Object of type type is not JSON serializable because the entry goes straight through _json.dumps, and @mattprinold's str(e) workaround is the right stopgap (thanks for digging that up). The docs example throwing is the immediate bug; explicit exception support with stack traces is the better fix and we'll look at it as part of this pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions