Skip to content

Commit

Permalink
[Internal][Executor] Add error target for batch engine error (microso…
Browse files Browse the repository at this point in the history
…ft#1380)

# Description

Add error target for batch engine error

# All Promptflow Contribution checklist:
- [x] **The pull request does not introduce [breaking changes].**
- [ ] **CHANGELOG is updated for new features, bug fixes or other
significant changes.**
- [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).**
- [ ] **Create an issue and link to the pull request to get dedicated
review from promptflow team. Learn more: [suggested
workflow](../CONTRIBUTING.md#suggested-workflow).**

## General Guidelines and Best Practices
- [x] Title of the pull request is clear and informative.
- [x] There are a small number of commits, each of which have an
informative message. This means that previously merged commits do not
appear in the history of the PR. For more information on cleaning up the
commits in your PR, [see this
page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md).

### Testing Guidelines
- [x] Pull request includes test coverage for the included changes.
  • Loading branch information
PeiwenGaoMS authored Dec 5, 2023
1 parent 72703dd commit 6cc2bcb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
16 changes: 14 additions & 2 deletions src/promptflow/promptflow/batch/_batch_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from promptflow.batch._result import BatchResult
from promptflow.contracts.flow import Flow
from promptflow.contracts.run_info import Status
from promptflow.exceptions import PromptflowException
from promptflow.exceptions import ErrorTarget, PromptflowException
from promptflow.executor._result import AggregationResult, LineResult
from promptflow.executor.flow_validator import FlowValidator
from promptflow.storage._run_storage import AbstractRunStorage
Expand Down Expand Up @@ -144,7 +144,19 @@ def run(
return BatchResult.create(
self._start_time, datetime.utcnow(), [], AggregationResult({}, {}, {}), status=Status.Canceled
)
raise e
elif isinstance(e, PromptflowException):
raise e
else:
# For unexpected error, we need to wrap it to SystemErrorException.
# This allows us to see the stack trace inside.
unexpected_error = UnexpectedError(
target=ErrorTarget.BATCH,
message_format=(
"Unexpected error occurred while executing the batch run. Error: {error_type_and_message}."
),
error_type_and_message=f"({e.__class__.__name__}) {e}",
)
raise unexpected_error from e
finally:
# destroy executor proxy if the batch run is not cancelled
# TODO: add a lock to avoid destroy proxy twice
Expand Down
9 changes: 7 additions & 2 deletions src/promptflow/promptflow/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class ErrorTarget(str, Enum):
"""The target of the error, indicates which part of the system the error occurs."""

EXECUTOR = "Executor"
BATCH = "Batch"
FLOW_EXECUTOR = "FlowExecutor"
NODE_EXECUTOR = "NodeExecutor"
TOOL = "Tool"
Expand Down Expand Up @@ -119,10 +120,14 @@ def module(self, value):
@property
def reference_code(self):
"""The reference code of the error."""
# In Python 3.11, the __str__ method of the Enum type returns the name of the enumeration member.
# However, in earlier Python versions, the __str__ method returns the value of the enumeration member.
# Therefore, when dealing with this situation, we need to make some additional adjustments.
target = self.target.value if isinstance(self.target, ErrorTarget) else self.target
if self.module:
return f"{self.target}/{self.module}"
return f"{target}/{self.module}"
else:
return self.target
return target

@property
def inner_exception(self):
Expand Down
28 changes: 28 additions & 0 deletions src/promptflow/tests/executor/unittests/batch/test_batch_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from pathlib import Path
from unittest.mock import patch

import pytest

from promptflow._core._errors import UnexpectedError
from promptflow.batch import BatchEngine
from promptflow.exceptions import ErrorTarget

from ...utils import get_yaml_file


@pytest.mark.unittest
class TestBatchEngine:
def test_batch_engine_error(self):
with pytest.raises(UnexpectedError) as e:
with patch(
"promptflow.batch._batch_inputs_processor.BatchInputsProcessor.process_batch_inputs"
) as mock_func:
mock_func.side_effect = Exception("test error")
batch_engine = BatchEngine(get_yaml_file("csharp_flow"))
batch_engine.run({}, {}, Path("."))
assert e.value.target == ErrorTarget.BATCH
assert isinstance(e.value.inner_exception, Exception)
assert e.value.error_codes == ["SystemError", "UnexpectedError"]
assert (
e.value.message == "Unexpected error occurred while executing the batch run. Error: (Exception) test error."
)

0 comments on commit 6cc2bcb

Please sign in to comment.