hf-actions commited on
Commit
afb566d
·
1 Parent(s): 5de9f75

fix: DNS precheck and retry/backoff for FB API calls; improved DNS logging

Browse files
Files changed (2) hide show
  1. app.py +24 -0
  2. post_to_facebook.py +29 -5
app.py CHANGED
@@ -7,6 +7,7 @@ import time
7
  import gradio as gr
8
  import threading
9
  import requests
 
10
  from dotenv import load_dotenv
11
 
12
  load_dotenv()
@@ -151,6 +152,20 @@ if __name__ == "__main__":
151
  if not fb_token or not fb_page:
152
  logger.error("Facebook token or page id missing")
153
  ok = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  else:
155
  # Try to inspect the token using the Graph API debug_token endpoint when possible
156
  # This provides detailed info (is_valid, expires_at, type) when app credentials are available
@@ -221,6 +236,15 @@ if __name__ == "__main__":
221
  lf.write(entry)
222
  except Exception:
223
  logger.exception("Failed to write token validation ok to log.txt")
 
 
 
 
 
 
 
 
 
224
  except Exception as e:
225
  logger.exception("Facebook token validation failed with exception")
226
  try:
 
7
  import gradio as gr
8
  import threading
9
  import requests
10
+ import socket
11
  from dotenv import load_dotenv
12
 
13
  load_dotenv()
 
152
  if not fb_token or not fb_page:
153
  logger.error("Facebook token or page id missing")
154
  ok = False
155
+ else:
156
+ # quick DNS resolution check to avoid noisy stack traces when DNS fails
157
+ try:
158
+ socket.getaddrinfo("graph.facebook.com", 443)
159
+ except Exception as e:
160
+ logger.error("DNS resolution failed for graph.facebook.com: %s", e)
161
+ try:
162
+ with open("log.txt", "a", encoding="utf-8") as lf:
163
+ lf.write(f"[{__import__('time').strftime('%Y-%m-%d %H:%M:%S')}] FB_DNS_RESOLUTION_FAILED {e}\n")
164
+ except Exception:
165
+ logger.exception("Failed to write DNS failure to log.txt")
166
+ ok = False
167
+ # skip further FB checks when DNS is not available
168
+ return ok
169
  else:
170
  # Try to inspect the token using the Graph API debug_token endpoint when possible
171
  # This provides detailed info (is_valid, expires_at, type) when app credentials are available
 
236
  lf.write(entry)
237
  except Exception:
238
  logger.exception("Failed to write token validation ok to log.txt")
239
+ except requests.exceptions.RequestException as e:
240
+ # network-related errors (including DNS/name resolution) are common in Spaces intermittently
241
+ logger.exception("Facebook token validation network failure: %s", e)
242
+ try:
243
+ with open("log.txt", "a", encoding="utf-8") as lf:
244
+ lf.write(f"[{__import__('time').strftime('%Y-%m-%d %H:%M:%S')}] FB_TOKEN_VALIDATION_NETWORK_EXCEPTION {e}\n")
245
+ except Exception:
246
+ logger.exception("Failed to write token validation exception to log.txt")
247
+ ok = False
248
  except Exception as e:
249
  logger.exception("Facebook token validation failed with exception")
250
  try:
post_to_facebook.py CHANGED
@@ -2,6 +2,9 @@ import os
2
  import argparse
3
  import logging
4
  import requests
 
 
 
5
  from dotenv import load_dotenv
6
 
7
  logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
@@ -22,13 +25,34 @@ def post_to_facebook(page_id: str, access_token: str, message: str, link: str |
22
  if link:
23
  payload["link"] = link
24
  logger.info("Posting to Facebook page %s", page_id)
25
- resp = requests.post(url, data=payload)
26
  try:
27
- resp.raise_for_status()
28
- except requests.HTTPError:
29
- logger.error("Facebook API error: %s", resp.text)
30
- _append_log(f"[{__import__('time').strftime('%Y-%m-%d %H:%M:%S')}] FB_POST_ERROR page={page_id} message={message[:120]!r} response={resp.text}")
31
  raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  data = resp.json()
33
  logger.info("Post successful: %s", data)
34
  # append a concise entry to log.txt for auditing
 
2
  import argparse
3
  import logging
4
  import requests
5
+ import socket
6
+ import time
7
+ from requests.exceptions import RequestException
8
  from dotenv import load_dotenv
9
 
10
  logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
 
25
  if link:
26
  payload["link"] = link
27
  logger.info("Posting to Facebook page %s", page_id)
28
+ # Ensure graph.facebook.com resolves before attempting to POST to avoid long, noisy stack traces
29
  try:
30
+ socket.getaddrinfo("graph.facebook.com", 443)
31
+ except Exception as e:
32
+ logger.error("DNS resolution failed for graph.facebook.com: %s", e)
33
+ _append_log(f"[{__import__('time').strftime('%Y-%m-%d %H:%M:%S')}] FB_DNS_RESOLUTION_FAILED {e}")
34
  raise
35
+
36
+ # Retry with exponential backoff for transient network issues
37
+ attempts = 4
38
+ backoff = 2
39
+ last_exc = None
40
+ for attempt in range(1, attempts + 1):
41
+ try:
42
+ resp = requests.post(url, data=payload, timeout=15)
43
+ resp.raise_for_status()
44
+ last_exc = None
45
+ break
46
+ except RequestException as e:
47
+ last_exc = e
48
+ logger.warning("Attempt %s/%s: Facebook POST failed: %s", attempt, attempts, e)
49
+ if attempt < attempts:
50
+ time.sleep(backoff)
51
+ backoff *= 2
52
+ else:
53
+ logger.error("All Facebook POST attempts failed")
54
+ _append_log(f"[{__import__('time').strftime('%Y-%m-%d %H:%M:%S')}] FB_POST_ERROR page={page_id} message={message[:120]!r} exception={e}")
55
+ raise
56
  data = resp.json()
57
  logger.info("Post successful: %s", data)
58
  # append a concise entry to log.txt for auditing