amber-lang / amber-lang/amber

[Feature] / [Question] / [RFC] Ability to access / propagate command stdout + stderr to the failed block

Open
#347 3 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
5.2k
Forks
145
Avg merge
5d 3h
Merged PRs (30d)
7

Description

## Description

It appears that today, there is no way to access stdout + stderr of a command which failed (exited with non zero status code) inside the `failed` block or outside of it as part of the command return value.

I tried multiple approaches without success - please correct me if I'm wrong and I missed something.

## Background, Context, Use Case

Today Amber already offers some improved error / failure handling of commands which exited with non-zero status code, but since I don't have access to command stdout + stderr, I can't improve and add additional user-friendly error handling in the `failed` block (or outside of it)

In ideal world, each program would exit with a different non-zero status code for each error scenario, but that's not a case with majority of the programs today. In a lot of cases only way to determine error type is to parse and inspect the command string output (stdout / stderr).

I know that one workaround I could perhaps use is to redirect command stderr output to stdout, but this is not ideal and still only works in case command exited with zero status code.

Let's take this code for example:

```amber
import * from "std"

main (args) {
echo ""
echo "scenario 1 - exit code 0 with failed block"
echo ""

let output = silent $ echo "stdout" ; >&2 echo "stderr" ; exit 0 $ failed {
echo "Should not get here"
}

echo ""
echo "output"
echo "{output}"
echo "status: {status}"
echo "end"

echo ""
echo "scenario 2 - exit code 2"
echo ""

let output = silent $ echo "stdout" ; >&2 echo "stderr" ; exit 2 $ failed {
echo "Inside failed block"
echo "status: {status}"
}

echo ""
echo "output"
echo "{output}"
echo "status: {status}"
echo "end"

echo ""
echo "scenario 3 - exit code 2 with unsafe"
echo ""

let output = silent unsafe $ echo "stdout" ; >&2 echo "stderr" ; exit 2 $

echo ""
echo "output"
echo "{output}"
echo "status: {status}"
echo "end"
}
```

Output will look like this:

```
$ bash test.sh

scenario 1 - exit code 0 with failed block

stderr

output
stdout
stauts: 0
end

scenario 2 - exit code 2

stderr
Inside failed block

output
stdout
stauts: 2
end

scenario 3 - exit code 2 with unsafe

stderr

output
stdout
stauts: 2
end

```

## Proposed Change / Implementation

I haven't had much time yet to check the internals and think how this could look, but since `status` expression is already available in the `failed` block we could perhaps try to redirect and capture stdout + stderr of each command and then make it available via special variables or expression inside the block.

Perhaps something along the lines of (pseudo code):

```
import * from "std"

main (args) {
// Option 1 via special variables / expression which is available inside and
// outside the failed block
let output = silent $ echo "stdout" ; >&2 echo "stderr" ; exit 2 $ failed {
echo "Inside failed block"
echo "status: {status}"
echo "stdout: {stdout}"
echo "stderr: {stderr}"

if contains(stdout, "errNoPermission") {
echo "Command returned no permission error."
echo "This likely indicates your session key has expired. Please visit XXX for more information on how to retrieve new or refresh the session key."
}
}

// Option 2 via return values
let stderr, stdout = silent $ echo "stdout" ; >&2 echo "stderr" ; exit 2 $ failed {
echo "Inside failed block"
echo "status: {status}"
echo "stdout: {stdout}"
echo "stderr: {stderr}"
}

echo "status: {status}"
echo "stdout: {stdout}"
echo "stderr: {stderr}"
}
```

Thanks.

## Related PRs, Issues

- This issue looks somewhat related, note sure if we should merge or mark mine as duplicate - https://github.com/amber-lang/amber/issues/287
- https://github.com/amber-lang/amber/issues/296

## Links

- Docs - https://docs.amber-lang.com/basic_syntax/commands

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.