Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ctx.print() statements are swallowed if fail_no_stacktrace() is called later #869

Open
AtomicOperation opened this issue Mar 7, 2025 · 3 comments
Labels
bxl Buck Extension Language

Comments

@AtomicOperation
Copy link

AtomicOperation commented Mar 7, 2025

Anything printed by ctx.print() isn't displayed if (later) fail_no_stacktrace() is called. Regular print statements are shown, but ofc those aren't displayed the next time if the result is cached.

def foo_impl(ctx):
    ctx.output.print("Test message\n")
    fail_no_stacktrace(f"Failure")
        
foo = bxl_main(
    impl = foo_impl,
    cli_args = {
    }
)

Output:

❯ buck2 bxl bxl//foo.bxl:foo        
Re-run the script with `-v5` to show the full stacktrace
fail: Failure

The actual use case is to eagerly build target libraries and ensure they're present locally on disk so that they can be linked by a CMake-based build script. (As a side note, that seems like a common enough thing that it would be good to have a complete example in the docs.)

We call ctx.output.ensure_multiple() and ctx.build() and if that fails print the error messages and return a nonzero exit code. To get this to work now, the best thing I could find is to create a multi-line error message and then pass that to fail_no_stacktrace(), but I think there's a footgun here if output is swallowed just because later there's an error. I also think there should be a straightforward way to tell the BXL script to return a nonzero exit code.

@Nero5023 Nero5023 added the bxl Buck Extension Language label Mar 7, 2025
@Nero5023
Copy link
Contributor

Nero5023 commented Mar 7, 2025

There would be an issue if we just output the ctx.output.print if failure in bxl.
BXL scripts can primarily be divided into two phases:

  • Phase 1 (Evaluation): The BXL script is interpreted. During this phase, calls to ctx.output.ensure(...) register artifacts that should be materialized later, but the actual materialization does not happen yet.
  • Phase 2 (Materialization): It materializes all artifacts previously registered via ctx.output.ensure(...).

Here is a potential issue if we output the ctx.output.print:
When we call fail_no_stacktrace, it would fail at phase 1 and skip phase 2. If there is some ctx.output.print(ensured_artifact) before fail_no_stacktrace, it would also print output the artifact's path in stdout. But since the skip the phase 2, the artifact will not be materialized and you got an invalid path.

I am working an a new ctx.output.stream api which would print out the message immediately if no ensured artifacts bounded if phase 1 and if it is bounded with ensured artifacts it will print out the message when the artifacts are ready. I would also support output the message using this api when it failed in your case whenever it is cached.

@AtomicOperation
Copy link
Author

I don't think that's an issue in practice? If the script fails, I wouldn't necessarily expect any libraries to have been materialized.

@Nero5023
Copy link
Contributor

Nero5023 commented Mar 7, 2025

But the semantic of ctx.ouput.print is that when you get the path of ensured artifact, it should be available.
You can use ctx.output.stream api later. My code is ready and waiting on review now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bxl Buck Extension Language
Projects
None yet
Development

No branches or pull requests

2 participants