skeeto / skewer-mode

Live web development in Emacs
The Unlicense
1.09k stars 57 forks source link

Can't get skewer-mode to work #27

Closed expez closed 11 years ago

expez commented 11 years ago

Hi, I've been trying for quite some time to get skewer-mode to work, but I can't seem to figure out what's wrong.

I grabbed skewer-mode, js2-mode and httpd from melpa earlier today, so I should have the latest version. I've tried using both Firefox and Chrome with the same result.

Using Emacs 24.3.1 I do the following:

  1. emacs -Q
  2. load js2-mode
  3. load simple-httpd
  4. load all the skewer files
  5. M-x run-skewer
  6. navigate to boids.js
  7. M-x skewer-load-buffer

In the browser nothing happens.

The tail of httpd is as follows:

(request
 (date "Fri,  9 Aug 2013 17:11:14 GMT")
 (address "127.0.0.1")
 (get "/skewer/script/1292688296640749368/boids.js")
 (headers
  ("GET" "/skewer/script/1292688296640749368/boids.js" "HTTP/1.1")
  ("Host" "127.0.0.1:8080")
  ("User-Agent" "Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0")
  ("Accept" "*/*")
  ("Accept-Language" "en-US,en;q=0.5")
  ("Accept-Encoding" "gzip, deflate")
  ("Referer" "http://127.0.0.1:8080/skewer/demo")
  ("Connection" "keep-alive")
  ("Content" "")))
(request
 (date "Fri,  9 Aug 2013 17:11:14 GMT")
 (address "127.0.0.1")
 (get "/skewer/post")
 (headers
  ("POST" "/skewer/post" "HTTP/1.1")
  ("Host" "127.0.0.1:8080")
  ("User-Agent" "Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0")
  ("Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
  ("Accept-Language" "en-US,en;q=0.5")
  ("Accept-Encoding" "gzip, deflate")
  ("Content-Type" "text/plain; charset=UTF-8")
  ("Referer" "http://127.0.0.1:8080/skewer/demo")
  ("Content-Length" "16")
  ("Connection" "keep-alive")
  ("Pragma" "no-cache")
  ("Cache-Control" "no-cache")
  ("Content" "{\"type\":\"error\"}")))
(error 500
       (wrong-type-argument stringp nil))

If I remove the condition-case from httpd--filter I get the following backtrace:

(wrong-type-argument stringp nil)
  propertize(nil font-lock-face skewer-error-face)
  (let* ((buffer (get-buffer "*skewer-repl*")) (face (cdr (assoc (cdr (assoc (quote type) log)) skewer-repl-types))) (output (propertize (cdr (assoc (quote value) log)) (quote font-lock-face) face))) (if buffer (progn (save-current-buffer (set-buffer buffer) (save-excursion (goto-char (point-max)) (forward-line 0) (backward-char) (insert (concat "\n" output "")))))))
  skewer-post-log(((type . "error")))
  (progn (skewer-post-log response))
  (if (member type (quote ("log" "error"))) (progn (skewer-post-log response)))
  (let ((type (cdr (assoc (quote type) response)))) (if (member type (quote ("log" "error"))) (progn (skewer-post-log response))))
  skewer-repl--response-hook(((type . "error")))
  funcall(skewer-repl--response-hook ((type . "error")))
  (while --dolist-tail-- (setq hook (car --dolist-tail--)) (funcall hook result) (setq --dolist-tail-- (cdr --dolist-tail--)))
  (let ((--dolist-tail-- skewer-response-hook) hook) (while --dolist-tail-- (setq hook (car --dolist-tail--)) (funcall hook result) (setq --dolist-tail-- (cdr --dolist-tail--))))
  (progn (let ((--dolist-tail-- skewer-response-hook) hook) (while --dolist-tail-- (setq hook (car --dolist-tail--)) (funcall hook result) (setq --dolist-tail-- (cdr --dolist-tail--)))))
  (let* ((result (json-read-from-string (cadr (assoc "Content" req)))) (id (cdr (assoc (quote id) result))) (type (cdr (assoc (quote type) result))) (callback (get-cache-table id skewer-callbacks))) (setq skewer--last-timestamp (float-time)) (if callback (progn (funcall callback result))) (if id (skewer-queue-client proc req) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (httpd-send-header proc "text/plain" 200 :Access-Control-Allow-Origin "*")) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))) (progn (let ((--dolist-tail-- skewer-response-hook) hook) (while --dolist-tail-- (setq hook (car --dolist-tail--)) (funcall hook result) (setq --dolist-tail-- (cdr --dolist-tail--))))))
  httpd/skewer/post(#<process httpd <127.0.0.1:49320>> "/skewer/post" (("{\"type\":\"error\"}")) (("POST" "/skewer/post" "HTTP/1.1") ("Host" "127.0.0.1:8080") ("User-Agent" "Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0") ("Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") ("Accept-Language" "en-US,en;q=0.5") ("Accept-Encoding" "gzip, deflate") ("Content-Type" "text/plain; charset=UTF-8") ("Referer" "http://127.0.0.1:8080/skewer/demo") ("Content-Length" "16") ("Connection" "keep-alive") ("Pragma" "no-cache") ("Cache-Control" "no-cache") ("Content" "{\"type\":\"error\"}")))
  funcall(httpd/skewer/post #<process httpd <127.0.0.1:49320>> "/skewer/post" (("{\"type\":\"error\"}")) (("POST" "/skewer/post" "HTTP/1.1") ("Host" "127.0.0.1:8080") ("User-Agent" "Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0") ("Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") ("Accept-Language" "en-US,en;q=0.5") ("Accept-Encoding" "gzip, deflate") ("Content-Type" "text/plain; charset=UTF-8") ("Referer" "http://127.0.0.1:8080/skewer/demo") ("Content-Length" "16") ("Connection" "keep-alive") ("Pragma" "no-cache") ("Cache-Control" "no-cache") ("Content" "{\"type\":\"error\"}")))
  (if (null servlet) (httpd--error-safe proc 404) (funcall servlet proc uri-path uri-query request))
  (if (and content-length (< (string-bytes content) (string-to-number content-length))) (process-put proc :previous-string string) (process-put proc :previous-string nil) (httpd-log (\` (request (date (\, (httpd-date-string))) (address (\, (car (process-contact proc)))) (get (\, uri-path)) (\, (cons (quote headers) request))))) (if (null servlet) (httpd--error-safe proc 404) (funcall servlet proc uri-path uri-query request)))
  (let* ((request (httpd-parse string)) (content-length (cadr (assoc "Content-Length" request))) (uri (cadar request)) (content (cadr (assoc "Content" request))) (parsed-uri (httpd-parse-uri (concat uri))) (uri-path (nth 0 parsed-uri)) (uri-query (append (nth 1 parsed-uri) (httpd-parse-args content))) (servlet (httpd-get-servlet uri-path))) (if (and content-length (< (string-bytes content) (string-to-number content-length))) (process-put proc :previous-string string) (process-put proc :previous-string nil) (httpd-log (\` (request (date (\, (httpd-date-string))) (address (\, (car ...))) (get (\, uri-path)) (\, (cons (quote headers) request))))) (if (null servlet) (httpd--error-safe proc 404) (funcall servlet proc uri-path uri-query request))))
  httpd--filter(#<process httpd <127.0.0.1:49320>> "POST /skewer/post HTTP/1.1
\nHost: 127.0.0.1:8080
\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0
\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
\nAccept-Language: en-US,en;q=0.5
\nAccept-Encoding: gzip, deflate
\nContent-Type: text/plain; charset=UTF-8
\nReferer: http://127.0.0.1:8080/skewer/demo
\nContent-Length: 16
\nConnection: keep-alive
\nPragma: no-cache
\nCache-Control: no-cache
\n
\n{\"type\":\"error\"}")

This is where my debug-fu came up short. Can you spot the problem?

skeeto commented 11 years ago

There are two things going on here.

The "demo" skewer page is a completely empty HTML document. It used to have both a canvas element and include jQuery, which is what allowed the boids source to be loaded directly into the demo page. The jQuery dependency has since been removed from Skewer as well as the canvas on the demo page.

If you want to play with the boids demo now, you'll need to host the example.html from the boids repository (not to be confused with Skewer's example.html which shouldn't be used directly), either with your own server or using simple-httpd or just use the online demo. Once it's hosted, inject a script tag fetching http://localhost:8080/skewer (8080 being the default port) into the page (if you didn't change the port) using the bookmarklet, or the user script, or just by adding the tag to example.html yourself (if locally hosted).

The error message is a separate issue and it came up because apparently Firefox changed its behavior. This is news to me, so thanks for posting the issue.

Previously, in Firefox the error event on window was only triggered for loading errors. In other browsers, including Chrome, this event is also triggered for asynchronous JavaScript errors. This is a really handy way for Skewer to learn errors in asynchronously running functions, but Firefox users had to forgo this feature since Firefox had no reasonable equivalent.

It looks like they finally added it to Firefox, but, unfortunately, it's incomplete. The event has no message property or any other property that provides any information about the error. This gets passed along to Emacs, which tries to fetch the missing property, gets nil instead, and tries to propertize it, signaling an error.

I just fixed this in dbea191. You should see "" (from Firefox only) instead of an Emacs error.

expez commented 11 years ago

Thanks for the quick fix and additional instructions. I got it working!