Sample Header Ad - 728x90

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