Lee-W commented on code in PR #49164:
URL: https://github.com/apache/airflow/pull/49164#discussion_r2299642110


##########
airflow-core/tests/unit/api_fastapi/common/test_exceptions.py:
##########
@@ -282,3 +295,91 @@ def test_handle_multiple_columns_unique_constraint_error(
 
             assert response_detail == expected_detail
             assert "INSERT INTO dag_run" in actual_statement
+        assert exeinfo_response_error.value.detail == expected_exception.detail
+
+
+class TestDagErrorHandler:
+    dag_error_handler = DagErrorHandler()
+
+    def test_handle_deserialization_error_with_value_error(self):
+        error_message = "Missing Dag ID in serialized Dag"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        value_error = ValueError(error_message)
+        deserialization_error.__cause__ = value_error
+
+        with pytest.raises(
+            HTTPException,

Review Comment:
   nit: we probalby would like to verify the status code as well. same for 
other tests



##########
airflow-core/src/airflow/serialization/serialized_objects.py:
##########
@@ -1932,11 +1932,26 @@ def serialize_dag(cls, dag: SdkDag) -> dict:
     @classmethod
     def deserialize_dag(cls, encoded_dag: dict[str, Any]) -> SerializedDAG:
         """Deserializes a DAG from a JSON object."""
-        if "dag_id" not in encoded_dag:
-            raise RuntimeError(
-                "Encoded dag object has no dag_id key.  You may need to run 
`airflow dags reserialize`."
-            )
+        try:
+            if "dag_id" not in encoded_dag:
+                raise RuntimeError(
+                    "Encoded dag object has no dag_id key.  You may need to 
run `airflow dags reserialize`."

Review Comment:
   ```suggestion
                       "Encoded dag object has no dag_id key. You may need to 
run `airflow dags reserialize`."
   ```



##########
airflow-core/tests/unit/api_fastapi/common/test_exceptions.py:
##########
@@ -282,3 +295,91 @@ def test_handle_multiple_columns_unique_constraint_error(
 
             assert response_detail == expected_detail
             assert "INSERT INTO dag_run" in actual_statement
+        assert exeinfo_response_error.value.detail == expected_exception.detail
+
+
+class TestDagErrorHandler:
+    dag_error_handler = DagErrorHandler()
+
+    def test_handle_deserialization_error_with_value_error(self):
+        error_message = "Missing Dag ID in serialized Dag"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        value_error = ValueError(error_message)
+        deserialization_error.__cause__ = value_error
+
+        with pytest.raises(
+            HTTPException,
+            match=re.escape(f"An error occurred while trying to deserialize 
Dag: {deserialization_error}"),
+        ):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_deserialization_error_with_runtime_error(self):
+        error_message = "Error during Dag serialization process"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        runtime_error = RuntimeError(error_message)
+        deserialization_error.__cause__ = runtime_error
+
+        expected_exception = HTTPException(
+            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            detail=f"An error occurred while trying to deserialize Dag: 
{deserialization_error}",
+        )
+
+        with pytest.raises(HTTPException, 
match=re.escape(expected_exception.detail)):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_deserialization_error_with_key_error(self):
+        key = "required_field"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        key_error = KeyError(key)
+        deserialization_error.__cause__ = key_error
+
+        expected_exception = HTTPException(
+            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            detail=f"An error occurred while trying to deserialize Dag: 
{deserialization_error}",
+        )
+        with pytest.raises(HTTPException, 
match=re.escape(expected_exception.detail)):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_real_dag_deserialization_error(self):
+        """Test handling a real Dag deserialization error with actual 
serialized Dag."""
+
+        # Create a test DAG

Review Comment:
   I feel like we can make the setup and teardown part as a fixture to simplify 
the test case.
   
   ```python
   @pytest.fixture
   def wrongly_serialized_dag(session: Session) -> None:
       bundle_name = "testing"
   
       session.add(DagBundleModel(name=bundle_name))
       session.commit()
   
       dag_id = "test_dag_for_error"
       ...
   
       dag_model = 
session.scalar(select(SerializedDagModel).where(SerializedDagModel.dag_id == 
dag_id))
       ...
   
       SerializedDagModel.write_dag(test_dag, bundle_name=bundle_name)
   
       yield
       
       session.query(SerializedDagModel).filter(SerializedDagModel.dag_id == 
dag_id).delete()
       session.commit()
   ```



##########
airflow-core/tests/unit/api_fastapi/common/test_exceptions.py:
##########
@@ -282,3 +295,91 @@ def test_handle_multiple_columns_unique_constraint_error(
 
             assert response_detail == expected_detail
             assert "INSERT INTO dag_run" in actual_statement
+        assert exeinfo_response_error.value.detail == expected_exception.detail
+
+
+class TestDagErrorHandler:
+    dag_error_handler = DagErrorHandler()
+
+    def test_handle_deserialization_error_with_value_error(self):
+        error_message = "Missing Dag ID in serialized Dag"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        value_error = ValueError(error_message)
+        deserialization_error.__cause__ = value_error
+
+        with pytest.raises(
+            HTTPException,
+            match=re.escape(f"An error occurred while trying to deserialize 
Dag: {deserialization_error}"),
+        ):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_deserialization_error_with_runtime_error(self):
+        error_message = "Error during Dag serialization process"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        runtime_error = RuntimeError(error_message)
+        deserialization_error.__cause__ = runtime_error
+
+        expected_exception = HTTPException(
+            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            detail=f"An error occurred while trying to deserialize Dag: 
{deserialization_error}",
+        )
+
+        with pytest.raises(HTTPException, 
match=re.escape(expected_exception.detail)):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_deserialization_error_with_key_error(self):
+        key = "required_field"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        key_error = KeyError(key)
+        deserialization_error.__cause__ = key_error
+
+        expected_exception = HTTPException(
+            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            detail=f"An error occurred while trying to deserialize Dag: 
{deserialization_error}",
+        )
+        with pytest.raises(HTTPException, 
match=re.escape(expected_exception.detail)):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_real_dag_deserialization_error(self):

Review Comment:
   ```suggestion
       def test_handle_real_dag_deserialization_error(self, session: Session) 
-> None:
   ```
   
   I think we can use `session` fixture instead of creating the session 
everything 



##########
airflow-core/tests/unit/api_fastapi/common/test_exceptions.py:
##########
@@ -282,3 +295,91 @@ def test_handle_multiple_columns_unique_constraint_error(
 
             assert response_detail == expected_detail
             assert "INSERT INTO dag_run" in actual_statement
+        assert exeinfo_response_error.value.detail == expected_exception.detail
+
+
+class TestDagErrorHandler:
+    dag_error_handler = DagErrorHandler()
+
+    def test_handle_deserialization_error_with_value_error(self):
+        error_message = "Missing Dag ID in serialized Dag"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        value_error = ValueError(error_message)
+        deserialization_error.__cause__ = value_error
+
+        with pytest.raises(
+            HTTPException,

Review Comment:
   These few can probably be refactored using 
`pytest.mark.paraparametreizemetreize`



##########
airflow-core/tests/unit/api_fastapi/common/test_exceptions.py:
##########
@@ -282,3 +295,91 @@ def test_handle_multiple_columns_unique_constraint_error(
 
             assert response_detail == expected_detail
             assert "INSERT INTO dag_run" in actual_statement
+        assert exeinfo_response_error.value.detail == expected_exception.detail
+
+
+class TestDagErrorHandler:
+    dag_error_handler = DagErrorHandler()
+
+    def test_handle_deserialization_error_with_value_error(self):
+        error_message = "Missing Dag ID in serialized Dag"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        value_error = ValueError(error_message)
+        deserialization_error.__cause__ = value_error
+
+        with pytest.raises(
+            HTTPException,
+            match=re.escape(f"An error occurred while trying to deserialize 
Dag: {deserialization_error}"),
+        ):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_deserialization_error_with_runtime_error(self):
+        error_message = "Error during Dag serialization process"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        runtime_error = RuntimeError(error_message)
+        deserialization_error.__cause__ = runtime_error
+
+        expected_exception = HTTPException(
+            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            detail=f"An error occurred while trying to deserialize Dag: 
{deserialization_error}",
+        )
+
+        with pytest.raises(HTTPException, 
match=re.escape(expected_exception.detail)):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_deserialization_error_with_key_error(self):
+        key = "required_field"
+        deserialization_error = DeserializationError("test_dag_id")
+
+        key_error = KeyError(key)
+        deserialization_error.__cause__ = key_error
+
+        expected_exception = HTTPException(
+            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+            detail=f"An error occurred while trying to deserialize Dag: 
{deserialization_error}",
+        )
+        with pytest.raises(HTTPException, 
match=re.escape(expected_exception.detail)):
+            self.dag_error_handler.exception_handler(None, 
deserialization_error)
+
+    def test_handle_real_dag_deserialization_error(self):
+        """Test handling a real Dag deserialization error with actual 
serialized Dag."""
+
+        # Create a test DAG
+        bundle_name = "testing"
+
+        # Create the bundle in the database first
+        with create_session() as session:
+            if session.query(DagBundleModel).filter(DagBundleModel.name == 
bundle_name).count() == 0:
+                session.add(DagBundleModel(name=bundle_name))
+                session.commit()

Review Comment:
   Why do we need to check here?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to