I want to print debug output on failure, but ERR trap doesn't fire
0
votes
0
answers
45
views
I want to only print the debug output on failure, this is my attempt:
#!/bin/bash
set -euo pipefail
dt-api() {
# shellcheck disable=SC2086
curl \
--fail-with-body \
--silent \
--show-error \
-H "X-Api-Key: $dt_api_key" \
${curl_opts-} \
"$dt_api_url/api/v1$1" \
"${@:2}"
}
post-sbom() {
local -r project_name=$1
local -r project_version=$2
local -r bom_path=$(readlink -f "$3")
dt-api "/bom" \
-F "autoCreate=true" \
-F "projectName=$project_name" \
-F "projectVersion=$project_version" \
-F "isLatest=true" \
-F "bom=@$bom_path"
}
debug_file=$(mktemp)
>&2 echo "Debug file: $debug_file"
readonly debug_file
exec 3> "$debug_file"
export BASH_XTRACEFD=3
# trap 'rm -f "$debug_file"' EXIT
trap 'touch ERR.marker; cat "$debug_file"' ERR
set -x
post-sbom foo bar target/bom.xml
echo Done
If curl fails (e.g. 401 or 404) the trap is not invoked. The script exits at this point.
Sample output from running rm ERR.marker; ./script
rm: cannot remove 'ERR.marker': No such file or directory
Debug file: /tmp/tmp.auETKRfIWu
curl: (22) The requested URL returned error: 404
$ echo $?
22
$ cat ERR.marker
cat: ERR.marker: No such file or directory
I added the touch ERR.marker
to rule out any redirection issues.
I can see the file is NOT created in this case.
If I change the trap to EXIT I get:
rm: cannot remove 'ERR.marker': No such file or directory
Debug file: /tmp/tmp.npNyUItX5o
curl: (22) The requested URL returned error: 404
+ post-sbom foo bar target/bom.xml
+ local -r project_name=foo
+ local -r project_version=bar
++ readlink -f target/bom.xml
+ local -r bom_path=/home/jakub/repos/permission-service/target/bom.xml
+ dt-api 2/bom -F autoCreate=true -F projectName=foo -F projectVersion=bar -F isLatest=true -F bom=@/home/jakub/repos/permission-service/target/bom.xml
+ curl --fail-with-body --silent --show-error -H 'X-Api-Key: INVALID' https://dependency-track.example.com/api/v12/bom -F autoCreate=true -F projectName=foo -F projectVersion=bar -F isLatest=true -F bom=@/home/jakub/repos/permission-service/target/bom.xml
+ touch ERR.marker
+ cat /tmp/tmp.npNyUItX5o
If I change the trap from ERR
to EXIT
then it prints the $debug_file
when the script aborts, but the EXIT
trap will also fire if script completes successfully.
I guess I could just use an EXIT
trap and clear it at the end of the script.
Using set -E
makes the trap fire, but now it fires multiple times, which is not what I want. Maybe I could truncate the file after printing it.
Another thing that seems to fix this is changing the line to.
post-sbom foo bar target/bom.xml || false
I guess that implies that a failing function call is not triggering the ERR trap?
Maybe there is a better approach to printing debug output on failure?
Asked by Jakub Bochenski
(325 rep)
Apr 9, 2025, 04:05 PM
Last activity: Apr 9, 2025, 05:48 PM
Last activity: Apr 9, 2025, 05:48 PM