Skip to content

Commit cd002e8

Browse files
committed
Improve sentry-autofix.sh logging for debuggability
Logs every step: git pull status, API HTTP codes, issue counts, seen IDs count, individual event fetch results, and Claude output. Errors are clearly labeled with ERROR/WARNING prefixes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3fc4a5a commit cd002e8

1 file changed

Lines changed: 63 additions & 18 deletions

File tree

scripts/sentry-autofix.sh

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,63 @@
33
# Reads SENTRY_AUTH_TOKEN from .env in the repo root.
44
# Run via cron: 0 9 * * * /path/to/repo/scripts/sentry-autofix.sh
55

6-
set -euo pipefail
6+
set -uo pipefail
77

88
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
99
LOG_FILE="${REPO_DIR}/.sentry-autofix.log"
1010
SEEN_FILE="${REPO_DIR}/.sentry-seen-issues.json"
1111
SENTRY_ORG="gamarr"
1212

13-
cd "$REPO_DIR"
14-
git pull --rebase origin main 2>/dev/null || true
13+
log() { echo "$(date): $1" >> "$LOG_FILE"; }
14+
15+
cd "$REPO_DIR" || { log "ERROR: Cannot cd to $REPO_DIR"; exit 1; }
16+
17+
log "=== Starting Sentry check ==="
18+
19+
# Pull latest
20+
if ! git pull --rebase origin main >> "$LOG_FILE" 2>&1; then
21+
log "WARNING: git pull failed, continuing with local state"
22+
fi
1523

1624
# Load credentials
25+
if [ ! -f "$REPO_DIR/.env" ]; then
26+
log "ERROR: .env file not found at $REPO_DIR/.env"
27+
exit 1
28+
fi
1729
set -a
1830
source "$REPO_DIR/.env"
1931
set +a
2032

21-
: "${SENTRY_AUTH_TOKEN:?Set SENTRY_AUTH_TOKEN in .env}"
33+
if [ -z "${SENTRY_AUTH_TOKEN:-}" ]; then
34+
log "ERROR: SENTRY_AUTH_TOKEN not set in .env"
35+
exit 1
36+
fi
2237

23-
log() { echo "$(date): $1" >> "$LOG_FILE"; }
24-
log "Checking Sentry for new issues..."
38+
log "Fetching unresolved issues from Sentry..."
2539

2640
# Fetch unresolved issues
27-
ISSUES=$(curl -sf -H "Authorization: Bearer ${SENTRY_AUTH_TOKEN}" \
28-
"https://sentry.io/api/0/organizations/${SENTRY_ORG}/issues/?query=is:unresolved&sort=date&limit=10")
41+
HTTP_CODE=$(curl -s -o /tmp/sentry-issues.json -w "%{http_code}" \
42+
-H "Authorization: Bearer ${SENTRY_AUTH_TOKEN}" \
43+
"https://sentry.io/api/0/organizations/${SENTRY_ORG}/issues/?query=is:unresolved&sort=date&limit=10")
44+
45+
if [ "$HTTP_CODE" != "200" ]; then
46+
log "ERROR: Sentry API returned HTTP $HTTP_CODE"
47+
[ -f /tmp/sentry-issues.json ] && cat /tmp/sentry-issues.json >> "$LOG_FILE"
48+
exit 1
49+
fi
50+
51+
ISSUES=$(cat /tmp/sentry-issues.json)
52+
ISSUE_COUNT=$(echo "$ISSUES" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))" 2>&1)
53+
log "Fetched $ISSUE_COUNT unresolved issues"
2954

3055
# Load seen IDs
3156
if [ -f "$SEEN_FILE" ]; then
32-
SEEN=$(cat "$SEEN_FILE")
57+
SEEN=$(cat "$SEEN_FILE")
58+
SEEN_COUNT=$(echo "$SEEN" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))" 2>&1)
59+
log "Loaded $SEEN_COUNT seen issue IDs"
3360
else
34-
SEEN="[]"
61+
SEEN="[]"
62+
log "No seen issues file, starting fresh"
3563
fi
3664

3765
# Find new error-level issues not in seen list
@@ -43,12 +71,17 @@ seen_ids = set(str(s) for s in seen)
4371
new = [i for i in issues if str(i['id']) not in seen_ids and i['level'] == 'error']
4472
if not new:
4573
sys.exit(1)
74+
for i in new:
75+
print(f\" - [{i['id']}] {i['title']} (count: {i['count']})\", file=sys.stderr)
4676
print(json.dumps([{'id': i['id'], 'title': i['title'], 'count': i['count'], 'firstSeen': i['firstSeen']} for i in new]))
47-
" 2>/dev/null) || {
48-
log "No new issues."
77+
" 2>> "$LOG_FILE") || {
78+
log "No new issues. Done."
4979
exit 0
5080
}
5181

82+
NEW_COUNT=$(echo "$NEW_ISSUES" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))")
83+
log "Found $NEW_COUNT new issue(s), fetching stack traces..."
84+
5285
# Fetch stack traces for each new issue
5386
DETAILS=$(echo "$NEW_ISSUES" | python3 -c "
5487
import json, sys, subprocess
@@ -61,13 +94,20 @@ for issue in issues:
6194
capture_output=True, text=True)
6295
if result.returncode == 0:
6396
issue['event'] = json.loads(result.stdout)
97+
print(f'Fetched event for issue {iid}', file=sys.stderr)
98+
else:
99+
print(f'WARNING: Failed to fetch event for issue {iid} (exit {result.returncode})', file=sys.stderr)
64100
print(json.dumps(issues, indent=2))
65-
")
101+
" 2>> "$LOG_FILE")
66102

67-
log "New issues found, invoking Claude..."
68-
echo "$DETAILS" >> "$LOG_FILE"
103+
if [ -z "$DETAILS" ]; then
104+
log "ERROR: Failed to fetch issue details"
105+
exit 1
106+
fi
107+
108+
log "Invoking Claude to analyze and fix..."
69109

70-
claude -p --model opus "New Sentry issues found. Here are the details:
110+
CLAUDE_OUTPUT=$(claude -p --model opus "New Sentry issues found. Here are the details:
71111
72112
$DETAILS
73113
@@ -78,6 +118,11 @@ For each issue:
78118
79119
After processing, update .sentry-seen-issues.json — append all new issue IDs (both fixed and skipped).
80120
Commit all changes and push to main.
81-
Keep fixes minimal. Do not refactor surrounding code." >> "$LOG_FILE" 2>&1
121+
Keep fixes minimal. Do not refactor surrounding code." 2>&1) || {
122+
log "ERROR: Claude exited with code $?"
123+
echo "$CLAUDE_OUTPUT" >> "$LOG_FILE"
124+
exit 1
125+
}
82126

83-
log "Done."
127+
echo "$CLAUDE_OUTPUT" >> "$LOG_FILE"
128+
log "=== Done ==="

0 commit comments

Comments
 (0)