{"record":{"id":"d8cfc5f7b42cc6eb","repo":"lfnovo/open-notebook","slug":"error-fetching-all-cls-table-name-str-e","errorCode":null,"errorMessage":"Error fetching all {cls.table_name}: {str(e)}","messagePattern":"Error fetching all (.+?): (.+?)","errorType":"exception","errorClass":"DatabaseOperationError","httpStatus":null,"severity":"critical","filePath":"open_notebook/domain/base.py","lineNumber":102,"sourceCode":"            if order_by:\n                validated_order_by = cls._validate_order_by(order_by)\n                query = f\"SELECT * FROM {table_name} ORDER BY {validated_order_by}\"\n            else:\n                query = f\"SELECT * FROM {table_name}\"\n\n            result = await repo_query(query)\n            objects = []\n            for obj in result:\n                try:\n                    objects.append(target_class(**obj))\n                except Exception as e:\n                    logger.critical(f\"Error creating object: {str(e)}\")\n\n            return objects\n        except Exception as e:\n            logger.error(f\"Error fetching all {cls.table_name}: {str(e)}\")\n            logger.exception(e)\n            raise DatabaseOperationError(e)\n\n    @classmethod\n    async def get(cls: Type[T], id: str) -> T:\n        if not id:\n            raise InvalidInputError(\"ID cannot be empty\")\n        try:\n            # Get the table name from the ID (everything before the first colon)\n            table_name = id.split(\":\")[0] if \":\" in id else id\n\n            # If we're calling from a specific subclass and IDs match, use that class\n            if cls.table_name and cls.table_name == table_name:\n                target_class: Type[T] = cls\n            else:\n                # Otherwise, find the appropriate subclass based on table_name\n                found_class = cls._get_class_by_table_name(table_name)\n                if not found_class:\n                    raise InvalidInputError(f\"No class found for table {table_name}\")\n                target_class = cast(Type[T], found_class)","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/open_notebook/domain/base.py#L84-L120","documentation":"get_all() wraps its database query in a broad try/except: any exception from repo_query, row deserialization (target_class(**row)), or the SurrealDB connection is logged and re-raised as DatabaseOperationError. It signals an infrastructure/deserialization failure, not bad input.","triggerScenarios":"SurrealDB is down or unreachable; the record shape doesn't match the model's Pydantic fields (schema drift after a migration); connection timeout; permission errors on the table. The exception's __cause__ holds the original error.","commonSituations":"Forgot to run `make database` before the API, schema migrations didn't run on startup (check API logs), a model field was renamed in Python but not migrated in SurrealDB, or stale docker container with old schema.","solutions":["Verify SurrealDB is running (make database / make status) and the API could reach it at startup","Inspect logs — logger.exception(e) prints the original traceback; fix the underlying cause","If it's deserialization, compare the model's Pydantic fields against actual records (schema drift) and let migrations run or fix the data","Catch DatabaseOperationError at the API layer and return a 503/500 rather than crashing"],"exampleFix":"// before\nobjects = await Note.get_all()  # raises DatabaseOperationError bare\n\n// after\nfrom open_notebook.domain.errors import DatabaseOperationError\ntry:\n    objects = await Note.get_all()\nexcept DatabaseOperationError as e:\n    logger.error(f\"DB unavailable: {e}\")\n    objects = []","handlingStrategy":"try-catch","validationCode":"null","typeGuard":null,"tryCatchPattern":"from open_notebook.domain.errors import DatabaseOperationError\ntry:\n    items = await Note.get_all()\nexcept DatabaseOperationError as e:\n    logger.exception(\"get_all failed\", exc_info=e)\n    raise HTTPException(status_code=503, detail=\"Database temporarily unavailable\")","preventionTips":["Start tiers in order: database → api → worker → frontend (make start-all)","Watch API startup logs to confirm migrations ran","Monitor SurrealDB health; alert on connection errors before they reach user paths"],"tags":["surrealdb","database","infrastructure","open-notebook"],"backgroundTag":"database-operation-failed","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}