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

Catch and elaborate errors for corrupt json or incorrect object hook #279

Closed
rwxayheee opened this issue Dec 11, 2024 · 1 comment
Closed
Assignees
Labels
enhancement New feature or request

Comments

@rwxayheee
Copy link
Contributor

rwxayheee commented Dec 11, 2024

There are several types of JSON files in the Meeko world. Many objects can be created from JSON (which is really convenient when put into use), but the errors are not so clear if there's a problem within the JSON file or the incorrect object hook. It might be helpful to catch and elaborate errors (just provide some quick hints) for bad input JSON or incorrect object hook.

There are some situations that the JSON can be loaded into a dict, but cannot be built into a valid Python object like Polymer. I wish there's a way to catch the problem, but I'm not so sure how to do it

@rwxayheee rwxayheee added the enhancement New feature or request label Dec 11, 2024
@rwxayheee rwxayheee self-assigned this Dec 12, 2024
@rwxayheee
Copy link
Contributor Author

Its really really not necessary unless more people want it. Here's a class to inherit from. Something like the following gives some hints on where the problem occurred (parsing, decoder function, object type) and avoids letting go a partial parse silently.

class BaseJSONParsable:

    # Define in Individual Subclasses 
    expected_json_keys = None
    object_hook = None 
    # and some decoder function

    # Inherit from_json and from_json_file
    @classmethod
    def from_json(cls, json_string):
        try: 
            obj = json.loads(json_string, object_hook=cls.object_hook)
            # Log mismatched keys (maybe not a fatal problem)
            if set(obj.keys()) != cls.expected_json_keys:
                logging.error(
                    f"Keys from JSON ({set(obj.keys())}) differ from "
                    f"expected keys ({cls.expected_json_keys})."
                )  
            # Success
            if isinstance(obj, cls): 
                return obj

        except Exception as decoder_error:     
            try: 
                obj = json.loads(json_string)
            # Error occurred while parsing JSON
            except Exception as parser_error: 
                raise RuntimeError(
                    f"Unable to parse the source JSON for {cls.__name__}: {parser_error}"
                )
            # Error occurred within the decoder function
            raise RuntimeError(
                f"An error occurred when creating {cls.__name__}: {decoder_error}"
            )
        # Failed to create obj
        raise ValueError(
            f"Unexpected object type created from JSON: {type(obj)}. "
            f"Expected object type is: {cls.__name__}."
        )
            
    @classmethod
    def from_json_file(cls, json_file): 
        with open(json_file, "r") as f: 
            json_string = f.read()
        return cls.from_json(json_string)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant