fix: harden shell scripts with error handling and null guards

- dashboard.sh: Add // [] jq null guard on .data.array.disks[] (L176-177)
  Resolves review thread PRRT_kwDOO6Hdxs5uvO21

- dashboard.sh: Default NAME to server key when env var unset (L221)
  Resolves review thread PRRT_kwDOO6Hdxs5uvO22

- unraid-query.sh: Check curl exit code, empty response, and JSON validity
  before piping to jq (L112-129)
  Resolves review thread PRRT_kwDOO6Hdxs5uvO24

- disk-health.sh: Guard against missing query script and invalid responses
  Resolves review thread PRRT_kwDOO6Hdxs5uvKrh
This commit is contained in:
Jacob Magar
2026-02-15 23:01:40 -05:00
parent fb86097709
commit c7ed077bb5
3 changed files with 32 additions and 5 deletions

View File

@@ -5,12 +5,25 @@
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
QUERY_SCRIPT="$SCRIPT_DIR/../scripts/unraid-query.sh" QUERY_SCRIPT="$SCRIPT_DIR/../scripts/unraid-query.sh"
if [[ ! -x "$QUERY_SCRIPT" ]]; then
echo "Error: Query script not found or not executable: $QUERY_SCRIPT" >&2
exit 1
fi
QUERY='{ array { disks { name device temp status isSpinning } } }' QUERY='{ array { disks { name device temp status isSpinning } } }'
echo "=== Disk Health Report ===" echo "=== Disk Health Report ==="
echo "" echo ""
RESPONSE=$("$QUERY_SCRIPT" -q "$QUERY" -f raw) RESPONSE=$("$QUERY_SCRIPT" -q "$QUERY" -f raw) || {
echo "Error: Query failed." >&2
exit 1
}
if [[ -z "$RESPONSE" ]] || ! echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then
echo "Error: Invalid or empty response from query." >&2
exit 1
fi
echo "$RESPONSE" | jq -r '.array.disks[] | "\(.name) (\(.device)): \(.temp)°C - \(.status) - \(if .isSpinning then "Spinning" else "Spun down" end)"' echo "$RESPONSE" | jq -r '.array.disks[] | "\(.name) (\(.device)): \(.temp)°C - \(.status) - \(if .isSpinning then "Spinning" else "Spun down" end)"'

View File

@@ -173,8 +173,8 @@ process_server() {
echo "" >> "$OUTPUT_FILE" echo "" >> "$OUTPUT_FILE"
echo "### Health" >> "$OUTPUT_FILE" echo "### Health" >> "$OUTPUT_FILE"
HOT_DISKS=$(echo "$RESPONSE" | jq -r '.data.array.disks[] | select(.temp > 45) | "- ⚠️ \(.name): \(.temp)°C (HIGH)"') HOT_DISKS=$(echo "$RESPONSE" | jq -r '(.data.array.disks // [])[] | select(.temp > 45) | "- ⚠️ \(.name): \(.temp)°C (HIGH)"')
DISK_ERRORS=$(echo "$RESPONSE" | jq -r '.data.array.disks[] | select(.numErrors > 0) | "- ❌ \(.name): \(.numErrors) errors"') DISK_ERRORS=$(echo "$RESPONSE" | jq -r '(.data.array.disks // [])[] | select(.numErrors > 0) | "- ❌ \(.name): \(.numErrors) errors"')
if [ -z "$HOT_DISKS" ] && [ -z "$DISK_ERRORS" ]; then if [ -z "$HOT_DISKS" ] && [ -z "$DISK_ERRORS" ]; then
echo "- ✅ All disks healthy" >> "$OUTPUT_FILE" echo "- ✅ All disks healthy" >> "$OUTPUT_FILE"
@@ -218,7 +218,7 @@ for server in "${SERVERS[@]}"; do
url_var="UNRAID_${server}_URL" url_var="UNRAID_${server}_URL"
key_var="UNRAID_${server}_API_KEY" key_var="UNRAID_${server}_API_KEY"
NAME="${!name_var}" NAME="${!name_var:-$server}"
URL="${!url_var}" URL="${!url_var}"
KEY="${!key_var}" KEY="${!key_var}"

View File

@@ -112,7 +112,21 @@ CURL_FLAGS=("-sL" "-X" "POST")
RESPONSE=$(curl "${CURL_FLAGS[@]}" "$URL" \ RESPONSE=$(curl "${CURL_FLAGS[@]}" "$URL" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-H "x-api-key: $API_KEY" \ -H "x-api-key: $API_KEY" \
-d "$PAYLOAD") -d "$PAYLOAD") || {
echo "Error: curl request failed (exit code $?). Check URL and network connectivity." >&2
exit 1
}
if [[ -z "$RESPONSE" ]]; then
echo "Error: Empty response from server." >&2
exit 1
fi
if ! echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then
echo "Error: Server returned invalid JSON. Response:" >&2
echo "$RESPONSE" | head -c 500 >&2
exit 1
fi
# Check for errors # Check for errors
if echo "$RESPONSE" | jq -e '.errors' > /dev/null 2>&1; then if echo "$RESPONSE" | jq -e '.errors' > /dev/null 2>&1; then