elisp debugging, show backtrace when function fails - debugging

I'd like to see the backtrace of error when I run this code.
(make-network-process :name (dbgp-make-listner-name 10004)
:server 1
:service 10004
:family 'ipv4
:nowait t
:noquery t
:filter 'dbgp-comint-setup
:sentinel 'dbgp-listener-sentinel
:log 'dbgp-listener-log)
https://github.com/gregsexton/ob-ipython/issues/4
This shows that I can see what's going on under make-network-process.
Debugger entered--Lisp error: (file-error "make client process failed" "connection refused" :name "localhost" :buffer # :host "localhost" :service 9988 :nowait nil)
make-network-process(:name "localhost" :buffer # :host "localhost" :service 9988 :nowait nil)
open-network-stream("localhost" # "localhost" 9988 :type plain :nowait nil)
byte-code . . .
url-open-stream("localhost" # "localhost" 9988)
url-http-find-free-connection("localhost" 9988)
url-http([cl-struct-url "http" nil nil "localhost" 9988 "/execute/default" nil nil t nil t] #128 "\302\303\304p#\210\300\305\240\210\301p\240\207" [(nil) (nil) url-debug retrieval "Synchronous fetching done (%S)" t] 5 "\n\n(fn &rest IGNORED)")
url-retrieve-internal("http://localhost:9988/execute/default" #128 "\302\303\304p#\210\300\305\240\210\301p\240\207" [(nil) (nil) url-debug retrieval "Synchronous fetching done (%S)" t] 5 "\n\n(fn &rest IGNORED)" nil nil)
url-retrieve("http://localhost:9988/execute/default" #[128
I tried
toggle-debug-on-error
edebug-eval-defun
But I can't see the backtrace..
on *Backtrace* buffer, I can see
Debugger entered: nil
(progn (debug) (make-network-process :name (dbgp-make-listner-name 10004) :server 1 :service 10004 :family (quote ipv4) :nowait t :noquery t :filter (quote dbgp-comint-setup) :sentinel (quote dbgp-listener-sentinel) :log (quote dbgp-listener-log)))
eval((progn (debug) (make-network-process :name (dbgp-make-listner-name 10004) :server 1 :service 10004 :family (quote ipv4) :nowait t :noquery t :filter (quote dbgp-comint-setup) :sentinel (quote dbgp-listener-sentinel) :log (quote dbgp-listener-log))) nil)
edebug-eval-defun(nil)
apply(edebug-eval-defun nil)
eval-defun(nil)
funcall-interactively(eval-defun nil)
call-interactively(eval-defun record nil)
command-execute(eval-defun record)
helm-M-x(nil "eval-defun")
funcall-interactively(helm-M-x nil "eval-defun")
call-interactively(helm-M-x nil nil)
command-execute(helm-M-x)
While the first trace shows what's going on behind make-network-process, my trace doesn't go deeper..

So the question is how to get more detail in the backtrace.
For byte-compiled elisp functions, loading the uncompiled version of the library in question will generally give you more detail, as the debugger can then show you exactly where in the function things happened.
However in this instance, make-network-process is a C function, so what you see now is all you're going to get out of the elisp debugger.
You'll have to examine/debug the source code in process.c if you want to know more.

Related

How to use 'conflicts' with ruby trolloop

Hi I'm using trollop to parse my command line options in ruby, I have four mutually exclusive options, and one option is always required.
I'm stuck trying to figure out how to ensure only one of the four options is passed. If called with more than one option I want the usage help (educate?) shown.
I see from the trollop source there's something called conflicts
http://www.rubydoc.info/gems/trollop/2.1.2/Trollop/Parser#conflicts-instance_method
that sounds like it does what I want (?) but I can't figure out how to use it correctly.
My current stanza is effectively this
require 'trollop'
opts = Trollop::options do
opt :last, "last"
opt :first, "first"
opt :file, "filename",
:type => String
opt :date, "date to read",
:type => Date
end
Trollop::die :file, "must exist" unless File.exist?(opts[:file]) if opts[:file]
thank you
You can add the conflicts as a line in your do block like this:
require 'trollop'
opts = Trollop::options(ARGV) do
opt :last, "last"
opt :first, "first"
opt :file, "filename", :type => String
opt :date, "date to read", :type => Date
conflicts :last, :first
end
puts "Your Options Are: "
puts opts
Then you get the following output:
ruby test_options.rb --last Last --first First
Error: --last conflicts with --first.
Try --help for help.

Http POST request with multipart/form-data using clj-ajax

I have an endpoint where I can upload a text file with curl like this:
curl -X POST -H "Content-Type: multipart/form-data" -F "file=#/resources/speciesDiffusion.tree" http://localhost:4000/continuous/tree
now I need to send a similar request from a browser, but
(ajax/ajax-request
{:uri (str "http://localhost:4000" "/continuous/tree")
:method :post
:params {:treefile file}
:handler #(println %1)
:format (ajax/text-request-format)
:response-format (ajax/json-response-format {:keywords? true})})
gives me a (nicely json converted, so I got that part going, which is nice) error response:
[false {:status 500, :status-text , :failure :error, :response {:timestamp 1494279686227, :status 500, :error Internal Server Error, :exception org.springframework.web.multipart.MultipartException, :message Current request is not a multipart request, :path /continuous/tree}}]
Also, in the browser I can see that the content-type headers is not correctly set, but I couldn't get it to work with any other combination of :format and :params.
There are some examples in the README of the cljs-ajax project. For example:
(let [form-data (doto
(js/FormData.)
(.append "id" "10")
(.append "file" js-file-value "filename.txt"))]
(POST "/send-file" {:body form-data
:response-format (raw-response-format)
:timeout 100}))
https://github.com/JulianBirch/cljs-ajax
As per my comment the problem was not in the request, but rather in the f-tion that dispatched it, i.e. I was reading the file content instead of sending the raw object like here:
(defn handle-file-upload [evt]
(let [target (.-currentTarget evt)
js-file (-> target .-files (aget 0))]
(do
(re-frame/dispatch [:post-file {:file js-file
:name (.-name js-file)}])
(set! (.-value target) ""))))
(defn upload-button []
(fn []
[:input {:class "none"
:id "file-upload"
:type "file"
:on-change #(handle-file-upload %)}]))
where
:post-file
is an event which invokes the handler which does the POST request.

Clojurescript Self Compile of def

Clojurescript 1.7 now supports self compilation (see here). I can compile code as follows
(ns self-compile.core
(:require cljs.js))
(enable-console-print!)
(set! cljs.js/*eval-fn* cljs.js/js-eval)
(def state (cljs.js/empty-state))
(cljs.js/eval-str state "(+ 1 2)"
(fn [response] ...))
This works fine for most code, except (def a 3) which gives the error #error {:message "ERROR", :data {:tag :cljs/analysis-error}, :cause #object[TypeError TypeError: Cannot set property 'a' of undefined]}.
How can I fix the setup?
I had the same issues, here's a few things I had to do go get it working:
Pass options to eval-str, you may have to pass options like:
:context :expr
:def-emits-var true
:ns 'cljs.user
Try evaling (ns cljs.user) first before evaling the def.
That should fix it.
See https://github.com/cljsinfo/cljs-api-docs/blob/catalog/refs/cljs.js_eval-str.md

clearing a session (logging a user out) in clojure-ring

With the impression that simply setting the request-map's :session to nil will cause a logout, my code looks like the following:
(GET "/logout" [ :as request]
(if-let [useremail (get-in request [:session :ph-auth-email])]
(-> (response {:status 200,
:body (pr-str "logged out " useremail),
:headers {"Content-Type:" "text/html"}})
(assoc request [:session nil]))))
But I get an error:
java.lang.Thread.run(Thread.java:745)
2015-02-18 09:29:05.134:WARN:oejs.AbstractHttpConnection:/logout
java.lang.Exception: Unrecognized body: {:status 200, :body "\"logged out \" \"sova\"", :headers {"Content-Type:" "text/html"}}
ring.util.response/response expects only the body as parameter since it'll build :status and :headers around it (see here). A map, however, is not a valid body - only strings, files, streams are allowed.
So, this is what causes the exception; now, on to your question: You can log out a user by setting :session to nil in your response (source) - which reduces your code to:
(GET "/logout" [:as request]
(if-let [useremail (get-in request [:session :ph-auth-email])]
{:status 200,
:body (pr-str "logged out " useremail),
:session nil, ;; !!!
:headers {"Content-Type" "text/html"}}))

Heroku clojure webapp crashes with error "That's not a task. Use "lein help" to list all tasks.'

I can deploy the sample heroku clojure webapp as described here. However a custom webapp, running fine locally, crashes on access.
heroku logs:
2013-11-28T02:01:57.142302+00:00 heroku[web.1]: State changed from crashed to starting
2013-11-28T02:01:57.124843+00:00 heroku[web.1]: Process exited with status 1
2013-11-28T02:02:02.579325+00:00 heroku[web.1]: Starting process with command `lein with-profile production trampoline run`
2013-11-28T02:02:03.366402+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Djava.rmi.server.useCodebaseOnly=true
2013-11-28T02:02:05.136478+00:00 app[web.1]: That's not a task. Use "lein help" to list all tasks.
2013-11-28T02:02:06.366976+00:00 heroku[web.1]: Process exited with status 1
2013-11-28T02:02:06.377083+00:00 heroku[web.1]: State changed from starting to crashed
I can't see heroku config listing JAVA_TOOL_OPTIONS either. What am i missing?
project.clj:
(defproject xxx "0.1.0"
:warn-on-reflection false
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/tools.nrepl "0.2.3"]
[ring "1.2.1"]
[ring/ring-jetty-adapter "1.1.6"]
[compojure "1.1.6"]
[enlive "1.1.4"]
[ring/ring-devel "1.1.0"]
[ring-basic-authentication "1.0.1"]
[com.cemerick/drawbridge "0.0.6" :exclusions [org.clojure/tools.nrepl]]
[environ "0.4.0"]]
:plugins [[lein-ring "0.8.8"]
[lein-environ "0.4.0"]]
:main xxx.web)
web.clj:
(ns xxx.web
(:require [compojure.core :refer [defroutes GET PUT POST DELETE ANY]]
[compojure.handler :refer [site]]
[compojure.route :as route]
[clojure.java.io :as io]
[ring.middleware.stacktrace :as trace]
[ring.middleware.session :as session]
[ring.middleware.session.cookie :as cookie]
[ring.adapter.jetty :as jetty]
[ring.middleware.basic-authentication :as basic]
[cemerick.drawbridge :as drawbridge]
[ring.middleware.params :as params]
[ring.middleware.keyword-params :as keyword-params]
[ring.middleware.nested-params :as nested-params]
[ring.middleware.session :as session]
[ring.middleware.basic-authentication :as basic]
[environ.core :refer [env]]
[xxx.templates :as templates]))
(defn- authenticated? [user pass]
;; TODO: heroku config:add REPL_USER=[...] REPL_PASSWORD=[...]
(= [user pass] [(env :repl-user false) (env :repl-password false)]))
(def ^:private drawbridge
(-> (drawbridge/ring-handler)
(session/wrap-session)
(basic/wrap-basic-authentication authenticated?)))
(defroutes app
(ANY "/repl" {:as req}
(drawbridge req))
(GET "/" []
{:status 200
:headers {"Content-Type" "text/html"}
:body (templates/index "Hello.") })
(ANY "*" []
(route/not-found (slurp (io/resource "404.html")))))
(defn wrap-error-page [handler]
(fn [req]
(try (handler req)
(catch Exception e
{:status 500
:headers {"Content-Type" "text/html"}
:body (slurp (io/resource "500.html"))}))))
(def drawbridge-handler
(-> (cemerick.drawbridge/ring-handler)
(keyword-params/wrap-keyword-params)
(nested-params/wrap-nested-params)
(params/wrap-params)
(session/wrap-session)))
(defn wrap-drawbridge [handler]
(fn [req]
(let [handler (if (= "/repl" (:uri req))
(basic/wrap-basic-authentication
drawbridge-handler authenticated?)
handler)]
(handler req))))
(defn -main [port]
(let [port (Integer. (or port (System/getenv "PORT")))]
;(jetty/run-jetty #'app {:port port :join? false})))
(jetty/run-jetty (wrap-drawbridge app) {:port port :join? false})))
You're probably using a different version of Leiningen locally than # Heroku.
From Heroku doc:
Leiningen 1.7.1 will be used by default, but if you have :min-lein-version "2.0.0" in project.clj (highly recommended) then the latest Leiningen 2.x release will be used instead.

Resources