git.fiddlerwoaroof.com
Browse code

Error handling in feed fetcher

Add restarts to feed fetcher for error handling

fiddlerwoaroof authored on 28/03/2017 23:09:06
Showing 1 changed files
... ...
@@ -4,10 +4,10 @@
4 4
 (defmacro setup-libraries-for-feeds (&body body)
5 5
   `(let ((plump:*tag-dispatchers* plump:*xml-tags*)
6 6
 	 (drakma:*drakma-default-external-format* :utf-8)
7
-         (drakma:*text-content-types* 
8
-           (pairlis '("application" "application")
9
-                    '("atom+xml"    "rss+xml")
10
-                    drakma:*text-content-types*)))
7
+	 (drakma:*text-content-types* 
8
+	  (pairlis '("application" "application" "application")
9
+		   '("atom+xml"    "rss+xml"     "xml")
10
+		   drakma:*text-content-types*)))
11 11
      ,@body))
12 12
 
13 13
 (defvar *user-agent* "alimenta/0.0")
... ...
@@ -24,16 +24,28 @@
24 24
   (let-bind-special-var-macro-body '*user-agent* user-agent body))
25 25
 
26 26
 (defun fetch-doc-from-url (url)
27
-  (setup-libraries-for-feeds 
28
-    (plump:parse (drakma:http-request url :user-agent *user-agent*))))
27
+  (setup-libraries-for-feeds
28
+    (loop
29
+       (restart-case (let ((data (drakma:http-request url :user-agent *user-agent*)))
30
+		       (setup-libraries-for-feeds 
31
+			 (return (plump:parse data))))
32
+	 (retry ()
33
+	   :report (lambda (s) (format s "Retry fetching the feed ~a" url)) )
34
+	 (skip-feed ()
35
+	   (return)
36
+	   :report (lambda (s) (format s "Skip fetching the url ~a" url)))))))
29 37
 
30
-(define-condition fetch-error () ())
38
+(define-condition fetch-error (error) ())
31 39
 (define-condition feed-ambiguous (fetch-error) ((choices :initarg :choices :initform nil)))
32 40
 (define-condition no-feed (fetch-error) ((url :initarg :url :initform nil)))
33 41
 
42
+(defun skip-feed (&optional condition)
43
+  (when-let ((restart (find-restart 'skip-feed condition)))
44
+    (invoke-restart restart)))
45
+
34 46
 (defun feed-ambiguous (choices)
35 47
   (error 'feed-ambiguous
36
-         :choices choices))
48
+	 :choices choices))
37 49
 
38 50
 (defun no-feed (url)
39 51
   (cerror "Skip this feed" 'no-feed :url url))
... ...
@@ -43,25 +55,28 @@
43 55
     (let* ((feeds (alimenta.discover:discover-feed (drakma:http-request url
44 56
 									:user-agent *user-agent*
45 57
 									:decode-content t)))
46
-	   (feeds (if type (remove-if-not (lambda (x) (eql type (car x))) feeds) feeds)))
47
-      (if (not feeds) (no-feed url)
48
-        (fetch-doc-from-url
49
-          (cdar 
50
-            (restart-case
51
-              (if (cdr feeds) (feed-ambiguous feeds) feeds)
52
-              (take-first-feed nil
53
-                               :report (lambda (s) (format s "Take the first feed"))
54
-                               feeds)
55
-              (take-nth-feed (n)
56
-                             :report (lambda (s) (format s "Take the nth feed"))
57
-                             (list (elt feeds n)))
58
-              (select-feed (selector)
59
-                           :report (lambda (s) (format s "Provide a function to select the right feed"))
60
-                           (find-if selector feeds)))))))))
58
+	   (feeds (if type (remove-if-not (lambda (x) (eql type (car x)))
59
+					  feeds)
60
+		      feeds)))
61
+      (if (not feeds)
62
+	  (no-feed url)
63
+	  (fetch-doc-from-url
64
+	   (cdar 
65
+	    (restart-case
66
+		(if (cdr feeds) (feed-ambiguous feeds) feeds)
67
+	      (take-first-feed nil
68
+		:report (lambda (s) (format s "Take the first feed"))
69
+		feeds)
70
+	      (take-nth-feed (n)
71
+		:report (lambda (s) (format s "Take the nth feed"))
72
+		(list (elt feeds n)))
73
+	      (select-feed (selector)
74
+		:report (lambda (s) (format s "Provide a function to select the right feed"))
75
+		(find-if selector feeds)))))))))
61 76
 
62 77
 (defun pull-feed (url &key detect type)
63 78
   (to-feed
64
-    (if detect
65
-      (fetch-feed-from-url url)
66
-      (fetch-doc-from-url url)) 
67
-    :type type))
79
+   (if detect
80
+       (fetch-feed-from-url url)
81
+       (fetch-doc-from-url url)) 
82
+   :type type))