refactor: add utility methods for getting display name and improve error messages (#5653)

* feat: add methods to access inputs' and outputs' display_name

- Updated error messages to use display names for inputs and outputs, improving clarity.
- Introduced utility methods for building consistent error messages related to inputs, outputs, and components.
- Added public methods to retrieve user-friendly display names for inputs and outputs.
- Refactored existing error handling to utilize the new messaging methods for better maintainability.

* refactor: enhance error message formatting for inputs, outputs, and components

- Updated error message formatting to place input, output, and component names at the beginning for better visibility, especially when messages are truncated.
- Changed the format of error messages to use square brackets for consistency and improved readability.
- Ensured that utility methods for building error messages maintain a user-friendly approach.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Gabriel Luiz Freitas Almeida 2025-01-20 09:53:31 -03:00 committed by GitHub
commit 204b4e10e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -389,7 +389,7 @@ class Component(CustomComponent):
"""
for input_ in inputs:
if input_.name is None:
msg = "Input name cannot be None."
msg = self.build_component_error_message("Input name cannot be None")
raise ValueError(msg)
self._inputs[input_.name] = deepcopy(input_)
@ -546,22 +546,21 @@ class Component(CustomComponent):
# If multiple matches are found, raise an error indicating ambiguity
if len(matching_pairs) > 1:
matching_pairs_str = self._build_error_string_from_matching_pairs(matching_pairs)
msg = (
f"There are multiple outputs from {value.__class__.__name__} "
f"that can connect to inputs in {self.__class__.__name__}: {matching_pairs_str}"
msg = self.build_component_error_message(
f"There are multiple outputs from {value.display_name} that can connect to inputs: {matching_pairs_str}"
)
raise ValueError(msg)
# If no matches are found, raise an error indicating no suitable output
if not matching_pairs:
msg = (
f"No matching output from {value.__class__.__name__} found for input '{input_name}' "
f"in {self.__class__.__name__}."
)
msg = self.build_input_error_message(input_name, f"No matching output from {value.display_name} found")
raise ValueError(msg)
# Get the matching output and input pair
output, input_ = matching_pairs[0]
# Ensure that the output method is a valid method name (string)
if not isinstance(output.method, str):
msg = f"Method {output.method} is not a valid output of {value.__class__.__name__}"
msg = self.build_component_error_message(
f"Method {output.method} is not a valid output of {value.display_name}"
)
raise TypeError(msg)
return getattr(value, output.method)
@ -685,19 +684,21 @@ class Component(CustomComponent):
input_value = self._inputs[name].value
if isinstance(input_value, Component):
methods = ", ".join([f"'{output.method}'" for output in input_value.outputs])
msg = (
f"You set {input_value.display_name} as value for `{name}`. "
f"You should pass one of the following: {methods}"
msg = self.build_input_error_message(
name,
f"You set {input_value.display_name} as value. You should pass one of the following: {methods}",
)
raise ValueError(msg)
if callable(input_value) and hasattr(input_value, "__self__"):
msg = f"Input {name} is connected to {input_value.__self__.display_name}.{input_value.__name__}"
msg = self.build_input_error_message(
name, f"Input is connected to {input_value.__self__.display_name}.{input_value.__name__}"
)
raise ValueError(msg)
self._inputs[name].value = value
if hasattr(self._inputs[name], "load_from_db"):
self._inputs[name].load_from_db = False
else:
msg = f"Input {name} not found in {self.__class__.__name__}"
msg = self.build_component_error_message(f"Input {name} not found")
raise ValueError(msg)
def _validate_outputs(self) -> None:
@ -1252,3 +1253,87 @@ class Component(CustomComponent):
description=TOOLS_METADATA_INFO,
),
)
def get_input_display_name(self, input_name: str) -> str:
"""Get the display name of an input.
This is a public utility method that subclasses can use to get user-friendly
display names for inputs when building error messages or UI elements.
Usage:
msg = f"Input {self.get_input_display_name(input_name)} not found"
Args:
input_name (str): The name of the input.
Returns:
str: The display name of the input, or the input name if not found.
"""
if input_name in self._inputs:
return getattr(self._inputs[input_name], "display_name", input_name)
return input_name
def get_output_display_name(self, output_name: str) -> str:
"""Get the display name of an output.
This is a public utility method that subclasses can use to get user-friendly
display names for outputs when building error messages or UI elements.
Args:
output_name (str): The name of the output.
Returns:
str: The display name of the output, or the output name if not found.
"""
if output_name in self._outputs_map:
return getattr(self._outputs_map[output_name], "display_name", output_name)
return output_name
def build_input_error_message(self, input_name: str, message: str) -> str:
"""Build an error message for an input.
This is a public utility method that subclasses can use to create consistent,
user-friendly error messages that reference inputs by their display names.
The input name is placed at the beginning to ensure it's visible even if the message is truncated.
Args:
input_name (str): The name of the input.
message (str): The error message.
Returns:
str: The formatted error message with display name.
"""
display_name = self.get_input_display_name(input_name)
return f"[Input: {display_name}] {message}"
def build_output_error_message(self, output_name: str, message: str) -> str:
"""Build an error message for an output.
This is a public utility method that subclasses can use to create consistent,
user-friendly error messages that reference outputs by their display names.
The output name is placed at the beginning to ensure it's visible even if the message is truncated.
Args:
output_name (str): The name of the output.
message (str): The error message.
Returns:
str: The formatted error message with display name.
"""
display_name = self.get_output_display_name(output_name)
return f"[Output: {display_name}] {message}"
def build_component_error_message(self, message: str) -> str:
"""Build an error message for the component.
This is a public utility method that subclasses can use to create consistent,
user-friendly error messages that reference the component by its display name.
The component name is placed at the beginning to ensure it's visible even if the message is truncated.
Args:
message (str): The error message.
Returns:
str: The formatted error message with component display name.
"""
return f"[Component: {self.display_name or self.__class__.__name__}] {message}"