Skip to main content

ActionErrorCtx

Context object passed to action error handlers containing information about the failed action.

ActionErrorCtx provides access to the stdout, stderr, and optionally output artifacts from a failed action. Error handler functions receive this context and use it to analyze the failure and produce structured ActionSubError objects for better error diagnostics and categorization.

The context object has three main attributes:

  • stderr: The stderr output from the failed action (as a string)
  • stdout: The stdout output from the failed action (as a string)
  • output_artifacts: A dictionary of output artifacts (if outputs_for_error_handler was specified in AnalysisActions.run)

Error handlers use this information to create categorized errors via new_sub_error() or parse compiler output using parse_with_errorformat().

Example:

def my_error_handler(ctx: ActionErrorCtx) -> list[ActionSubError]:
errors = []

# Check stderr for specific error patterns
if "compilation failed" in ctx.stderr.lower():
errors.append(ctx.new_sub_error(
category = "compilation_error",
message = "Compilation failed - check syntax and imports",
show_in_stderr = True,
))

# Parse structured error output using errorformat
if "error:" in ctx.stderr:
# Parse errors like "file.rs:42:10: error: expected semicolon"
parsed_errors = ctx.parse_with_errorformat(
category = "syntax_error",
error = ctx.stderr,
errorformats = ["%f:%l:%c: %m"],
)
errors.extend(parsed_errors)

# Access output artifacts for structured error data
if ctx.output_artifacts:
for artifact, value in ctx.output_artifacts.items():
error_json = value.read_json()
if "errors" in error_json:
for err in error_json["errors"]:
errors.append(ctx.new_sub_error(
category = err.get("code", "unknown"),
message = err.get("message"),
file = err.get("file"),
lnum = err.get("line"),
))

return errors

# Use the error handler in an action
def _impl(ctx):
ctx.actions.run(
cmd_args(["compiler", "main.rs"]),
category = "compile",
error_handler = my_error_handler,
)

ActionErrorCtx.new_sub_error

def ActionErrorCtx.new_sub_error(
*,
category: str,
message: None | str = None,
file: None | str = None,
lnum: None | int = None,
end_lnum: None | int = None,
col: None | int = None,
end_col: None | int = None,
error_type: None | str = None,
error_number: None | int = None,
show_in_stderr: bool = False,
subcategory: None | str = None,
remediation: None | str = None,
) -> ActionSubError

Create a new sub error, specifying an error category name, optional message, and optional location information.

The category should be finer grain error categorizations provided by the rule authors, and tend to be language specific. These should not be any kind of shared concepts among all errors for all languages/rules. For example, timeouts and infra errors should not go here - buck2 tries to categorize these types of errors automatically. An example of a finer grain error category may be the error code for rustc outputs.

'category': Required, useful for providing a more granular error category for action errors. 'message': Optional, provide users with additional context about the error to help with debugging/understandability/resolution, etc. 'file': Optional, file path where the error occurred. 'lnum': Optional, line number where the error occurred. 'end_lnum': Optional, end line number for multi-line error spans. 'col': Optional, column number where the error occurred. 'end_col': Optional, end column number for error ranges. 'error_type': Optional, type of error (e.g., error, warning, info). 'error_number': Optional, numeric error code. 'show_in_stderr': Optional, whether to show this error in stderr (default: false).

The message will be emitted to the build report, and to the stderr in the error diagnostics section.


ActionErrorCtx.output_artifacts

ActionErrorCtx.output_artifacts: dict[Artifact, ArtifactValue]

Allows the output artifacts to be retrieve if outputs_for_error_handler is set and the output artifact exists. This is useful for languages with structured error output, making the error retrieval process simpler.

This is also the recommended way to retrieve file path and line number, as reliably extracting that information from stdout/stderr can be challenging


ActionErrorCtx.parse_with_errorformat

def ActionErrorCtx.parse_with_errorformat(
*,
category: str,
error: str,
errorformats: list[str] | tuple[str, ...],
) -> list[ActionSubError]

Parse error text using vim errorformat patterns to create structured error information. This method leverages vim's proven errorformat system to extract file paths, line numbers, and error messages from compiler/tool output, automatically creating ActionSubError objects.

For errorformat pattern syntax, see: https://neovim.io/doc/user/quickfix.html#errorformat

Multiple patterns can be provided and will be tried in order until one matches. This is useful for tools that may output errors in different formats.

Args:

  • category: Base category name for the generated sub-errors (e.g., "rust", "gcc")
  • error: The error text to parse (typically stderr or stdout from the failed action)
  • errorformats: List of vim errorformat pattern strings to try matching against

Returns a list of ActionSubError objects with structured error information including file locations when successfully parsed from the error text.


ActionErrorCtx.stderr

ActionErrorCtx.stderr: str

Retrieve the stderr of the failed action. Can use string/regex matching to identify the error in order to categorize it.


ActionErrorCtx.stdout

ActionErrorCtx.stdout: str

Retrieve the stdout of the failed action. Can use string/regex matching to identify the patterns in order to categorize it.