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: for input_ in inputs:
if input_.name is None: 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) raise ValueError(msg)
self._inputs[input_.name] = deepcopy(input_) self._inputs[input_.name] = deepcopy(input_)
@ -546,22 +546,21 @@ class Component(CustomComponent):
# If multiple matches are found, raise an error indicating ambiguity # If multiple matches are found, raise an error indicating ambiguity
if len(matching_pairs) > 1: if len(matching_pairs) > 1:
matching_pairs_str = self._build_error_string_from_matching_pairs(matching_pairs) matching_pairs_str = self._build_error_string_from_matching_pairs(matching_pairs)
msg = ( msg = self.build_component_error_message(
f"There are multiple outputs from {value.__class__.__name__} " f"There are multiple outputs from {value.display_name} that can connect to inputs: {matching_pairs_str}"
f"that can connect to inputs in {self.__class__.__name__}: {matching_pairs_str}"
) )
raise ValueError(msg)
# If no matches are found, raise an error indicating no suitable output # If no matches are found, raise an error indicating no suitable output
if not matching_pairs: if not matching_pairs:
msg = ( msg = self.build_input_error_message(input_name, f"No matching output from {value.display_name} found")
f"No matching output from {value.__class__.__name__} found for input '{input_name}' "
f"in {self.__class__.__name__}."
)
raise ValueError(msg) raise ValueError(msg)
# Get the matching output and input pair # Get the matching output and input pair
output, input_ = matching_pairs[0] output, input_ = matching_pairs[0]
# Ensure that the output method is a valid method name (string) # Ensure that the output method is a valid method name (string)
if not isinstance(output.method, str): 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) raise TypeError(msg)
return getattr(value, output.method) return getattr(value, output.method)
@ -685,19 +684,21 @@ class Component(CustomComponent):
input_value = self._inputs[name].value input_value = self._inputs[name].value
if isinstance(input_value, Component): if isinstance(input_value, Component):
methods = ", ".join([f"'{output.method}'" for output in input_value.outputs]) methods = ", ".join([f"'{output.method}'" for output in input_value.outputs])
msg = ( msg = self.build_input_error_message(
f"You set {input_value.display_name} as value for `{name}`. " name,
f"You should pass one of the following: {methods}" f"You set {input_value.display_name} as value. You should pass one of the following: {methods}",
) )
raise ValueError(msg) raise ValueError(msg)
if callable(input_value) and hasattr(input_value, "__self__"): 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) raise ValueError(msg)
self._inputs[name].value = value self._inputs[name].value = value
if hasattr(self._inputs[name], "load_from_db"): if hasattr(self._inputs[name], "load_from_db"):
self._inputs[name].load_from_db = False self._inputs[name].load_from_db = False
else: 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) raise ValueError(msg)
def _validate_outputs(self) -> None: def _validate_outputs(self) -> None:
@ -1252,3 +1253,87 @@ class Component(CustomComponent):
description=TOOLS_METADATA_INFO, 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}"