tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.57k stars 377 forks source link

DoesNotExist can be more useful #1635

Closed BraveEggTart closed 3 months ago

BraveEggTart commented 4 months ago

Is your feature request related to a problem? Please describe. When I use the Model.get() method and a DoesNotExist exception occurs because there is no corresponding record in the database, the provided error message is often not specific enough for me to quickly identify which Model is involved. The message "Object does not exist" is too generic.  In such cases, it would be more helpful to have a more specific error message that indicates which Model is affected by the issue. I suggest enhancing the DoesNotExist exception handling to provide more detailed information about the Model where the error occurred, rather than a generic message.  This enhancement would greatly assist developers in quickly pinpointing the source of the problem when a DoesNotExist exception is raised during the Model.get() operation.

Describe the solution you'd like

    async def _execute(self) -> List[MODEL]:
        instance_list = await self._db.executor_class(
            model=self.model,
            db=self._db,
            prefetch_map=self._prefetch_map,
            prefetch_queries=self._prefetch_queries,
            select_related_idx=self._select_related_idx,
        ).execute_select(self.query, custom_fields=list(self._annotations.keys()))
        if self._single:
            if len(instance_list) == 1:
                return instance_list[0]
            if not instance_list:
                if self._raise_does_not_exist:
-                   raise DoesNotExist("Object does not exist")
+                   raise DoesNotExist(
+                       f"{self.model._meta.table_description} does not exist"
+                   )
                return None  # type: ignore
            raise MultipleObjectsReturned("Multiple objects returned, expected exactly one")
        return instance_list

Describe alternatives you've considered At first, I tried to catch exceptions at every call to Model. get(), and as the number of modifications increased, I implemented a BaseModel() that handled DoesNotExist information, which all of my models inherited. Afterwards, I also tried to use monkey_patches to modify the _excecute method. But none of these can satisfy me, so I want to solve this problem once and for all. Directly modifying DoesNotExist is also a method, but it involves a lot of parts and I'm not sure if this is what you want to see, so I only modified one

Additional context I checked the post commit information and found that this line was directly submitted to the code repository and has not been modified. Therefore, I cannot determine whether the current prompt information is a carefully considered result. In terms of modifying the plan, I noticed that there were multiple uses of the _meta attribute in the same file, so I also used _meta to organize prompt information. However, even so, there is still an issue of unclear prompt information because table_description does not always have a value. The good thing I can think of is that I only need to configure table_description for the model I want to see prompts for

I'm not sure if my issue meets the requirements. If it doesn't, please modify or close it. By the way, Tortoise-orm is an orm framework that I love everywhere. I wish all developers a smooth life and a happy day!

abondar commented 3 months ago

Hi!

I don't think there should be any problem with referring model or it's meta in those methods (there are 2 other places that raises same error)

You can make PR with modification of these places, so error would be more helpful Also fixing error

raise MultipleObjectsReturned("Multiple objects returned, expected exactly one")

would be nice

I don't think you need to use table_description, you can just go with self.model.__name__

abondar commented 3 months ago

Duplicate of #741, merged fix for it, will release as 0.21.4 in some time