Fork me on GitHub
Drew Verlee02:10:55

How do i represent a jodaTime object in my code for a test? If i just put the #object... i get an error about a tag literal reader.

Drew Verlee02:10:08

put another way, if i eval the code and use the output in my test then i get an error. #object[org.joda.time.DateTime 0x2b69f59 "0085-04-07T00:00:00.000Z"] isn't something i can read back into the repl.


@drewverlee Are you wanting to use joda time directly or are you using clj-time?

Drew Verlee02:10:59

I'm just calling functions in the clj-time namespace. i haven't had to do more then that to get the functionality i want.


That's all I've ever needed too - I'm away from the computer, but I think you can use the isequal method and compare your object against another that your test creates. Is that along the lines of what you wanted?

Drew Verlee02:10:41

oh, yea. that makes perfect sense

Drew Verlee02:10:26

This is what i get for trying to work while half asleep.


If you're using the before and after comparisons, one is inclusive and one is exclusive - it totally messes me up if I forget. Good to see you on here too, it was fun hanging out at he conj!


@drewverlee I'm one of the clj-time maintainers so let me know if there are specific questions I can help with...


(at work we're in the process of migrating to which is a nice, thin wrapper around Java Time introduced in Java 8)


What’s the most straight forward way to print whatever is coming in or out of a function? or in between forms?


Say I just want to know whats passing in between somewhere as quickly and with as less modifications to de code as possible


I.e. What’s the output of edn/read-string in the following snippet?

(def app-schema
  (-> "src/get_it_right/schema.edn"
      (attach-resolvers {:get-product get-product
                         :get-products get-products
                         :get-product-price-history get-product-price-history
                         :scrape-products scrape-products
                         :signin signin
                         :signup signup
                         :signout signout
                         :request-password-reset request-password-reset
                         :reset-password reset-password})


But also whathever the one function returns here:

(defn signup
  [_ctx {:keys [email password]} _val]
  (one pool (user/create-user
             {:email email
              :password password})))


For the first one I guess I could do:

(doto prn)
But what if I want to print the value along with a label to stdout? like "look here: " val


(doto (#(prn "here: " %))) is no longer as succint


Is there anything closer to elixir’s inspect ( in the standard library?


I.e. Take a value, print it to stdout with an optional label and return that same value unchanged?


Something like:

( inspect "here:")  -- Takes the output of edn/read-string, prints it to stdout after "here: " and passes it along.


I just went through the trouble of setting up sayid out of frustration


VERY impressed, best debugging experience I’ve had in my life.


is there a way I can extract source information from data passed into a macro and use it to provide helpful error messages pointing at the offending expression?


if the solution is a macro, you need the compiler for it


maybe I’m misreading that


hey again guys ! finally I’ve setup my application to use components ( thanks @noisesmith ) removed the lein-ring and runnin gmy application from REPL (go) after I call (go) my components boots up and the web-server as well ( web-server is one compoent ) and blocks my REPL ( waiting for request) how you guys normally does ? create a new system without web-server for the REPL ?


typically I’d put the web server process in a future, and attach that future to the component


@oliv depending on which server you are using, there is likely an optional argument to run in the background


but more generally, if a component needs something to continue running, attaching a future to the component (then making sure it exits and cleans up when stopped) is the thing to do


sounds interesting the future approach ( pretty sure I have to study a little more to be able execute with future )


do you have any example for that ?


btw: I’m using jetty


and how is your workflow, every time you change the source code you (stop) / (start) the components again ?


future is pretty easy - change (f) to (future (f)) - the biggest gotcha is that if it throws, you don’t see the error until something tries to dereference the future


run-jetty definitely has an option for running in the background (run-jetty ... :join? false)


some code doesn’t require a stop/start but that cycle should be short enough that it doesn’t matter much


Cool, so regarding the star / stop cycle, supposing I'm changing some function on my handler , eventually I will want to restart the server to test my fix


Do you do it manually or something else is listening for changes and restart the components to you ?


either can happen, but there’s nothing doing that automatically by default - I restart by hand after reloading my code


Yeah, same here. Yeah definitely I will run my jetty on background


also, a common trick is to pass the var for your handler to the server process, rather than the handler function itself - this ensures that the var is freshly looked up and dereferenced each time it is called. But this is incompatible with which deletes vars from namespaces and makes new ones


Releasing my repl , thank you for your time , let me know if you have any place for donation :)


I'm using the refresh , I confess I did not understand very well the var for your handler ...


Hopefully I will soon understand what you said


#'handler is the var that contains handler


if you call it, it calls handler after looking it up


if you call (run-jetty handler …) it looks up handler once, and then jetty just uses that


if you call (run-jetty #’handler …) it uses the var, which means it looks up the current value every time, which means it sees the new definition if you redefine it


@oliv perhaps this helps

(ins)user=> (defn do-foo [] :old-value)
(ins)user=> (defn capture [f] (fn [] (f)))
(ins)user=> (def f1 (capture do-foo))
(ins)user=> (def f2 (capture #'do-foo))
(ins)user=> (f1)
(ins)user=> (f2)
(ins)user=> (defn do-foo [] :new-value)
(ins)user=> (f1)
(ins)user=> (f2)


the difference between capturing do-foo vs. #'do-foo


Hello all, I am trying to get Leiningen set up on Fedora and I am having issues. Have been following the install instructions and they don't seem to be working for me. Could someone please help me? If Leiningen was on rpm this would be much easier as well, but it doesn't seem to be.


What’s the problem?


I am having issues running the script. Do I save the script with, or simply lein?


lein is the shell script - it installs everything else


Easiest if you save the script as lein


I usually save mine to ~/bin/lein


also you need to set it to be executable


OK, so my script is saved in /bin/lein


that’s a weird place to put it - /bin is typically for system level stuff


Ok, you might have some permissions issues if you put it there.


It’s better in ~/bin, then you don’t have to use sudo for updates and such

dpsutton18:10:17 on their page they suggest a place like ~/bin which is drastically different from /bin


most idiomatic on a *nix system would be to put it in /usr/local/bin or an individual user’s ~/bin/


but of course you have to have ~/bin in your PATH


ah, @dpsutton I didn't realize those 2 are different


sadly on OSX there are system level tools that mess with /usr/local/bin which is totally wrong - but no such problem on fedora


@adamfranzen Yes, ~/bin means you make a bin directory in your home dir.


and there’s also some setup you need to do to make sure your $PATH contains ~/bin


and then in ~/.profiles you can PATH="$HOME/bin:$PATH


ok, so I am emberassed to say, but I cannot access /bin. How do I access?


it belongs to root


only the package manager should be putting things there or removing things from it


that's why it's not a great place to put something there. it's very near and dear to your system


as in I cannot move mv ~/Downloads/lein /bin


right, you shouldn’t be doing that


That’s good because you don’t want to do that


You need the tilde in front of the /bin


mv ~/Downloads/lein ~/bin


Adam, let's talk commands over before we run them. we'll get you set up 🙂


~/bin is a shell syntax that expands to $HOME/bin/


that may have sounded condescending and i really don't mean it that way. but feel free to ask about a command before you run it if you like


☝️ no sweat, I appreciate the help. I am new to UNIX thanks for the help


Unix directory structure is kinda confusing, so no worries


And it is a bit different between different distros to make it even more confusing


~bin mv ~/Downloads/lein ~/bin
mv: cannot stat '/home/afran/Downloads/lein': No such file or directory


Oh wait, it can’t find your downloaded file


Just wget it? :)


it probably downloaded as or leiningen or something


you can use ls to see what is in ~/Downloads


we are all on pins and needles here haha


Sorry to leave you hanging guys. I got it figured out. Details to follow...


A coworker came in and distracted me ha


Hi, I’m using, the request headers are lowercase, but that’s okey, but seems like the response are lowercase as well, is there anyway to change that? a middleware or something?


I’ve used ring for years and this has never been a problem - what specifically is going wrong?


Clients who check headers in a case-sensitive way


if nothing else you can explicitly return a hash-map {:headers {.. ...} :status ... :body ...}


it should merge any headers under that key into the response


I do that

(defn- handler [request]
  (let [response (rfour/request (slurp (:body request))
                                (settings [:rabbitmq :exchange :topic])
                                (path->rk (request :uri))
                                :headers (merge {"w-path" (path-rstrip (request :uri))
                                                 "w-method" (string/upper-case (name (request :request-method)))
                                                 "w-query" (request :query-string)
                                                 "w-segments-length" (-> (request :uri) (path-strip) (path-segments) (count))}
                                                (-> (request :uri) (path-strip) (path-segments) (request-segments))
                                                (-> (request :headers) (request-headers))))]
    (println (response-headers (@response :headers)))
    {:status (response-status request @response)
     :headers (response-headers (@response :headers))
     :body (apply str (map char (@response :body)))}))
The print
{Content-Type application/json}
The response at postman
content-length →76
content-type →application/json
date →Fri, 27 Oct 2017 19:04:53 GMT
server →Jetty(9.2.21.v20170120)


There are some clientes (at least in Brazil) who is very boring about those kind of things


they are expecting Content-Type?


> Each header field consists of a case-insensitive field name followed > by a colon (":"), optional leading whitespace, the field value, and > optional trailing whitespace.


well nice to know that actual answer, even if it doesn't help


Yeah, they go against some things… sad but true


#'handler` is the var that contains `handler`
if you call it, it calls handler after looking it up
if you call (run-jetty handler …) it looks up handler once, and then jetty just uses that
if you call (run-jetty #'handler …) it uses the var, which means it looks up the current value every time, which means it sees the new definition if you redefine it
@noisesmith thank you again , mind blowing !!! I thought handler was the symbol which points to the Var #'handler which points to the value ( the function )


right - but the question is when (how often) that lookup is done


handler is looked up once (if provided as an arument) or every time (if compiled into a form)


#’handler is looked up every time, period


yeah ! makes completly sense , please put your crypto wallet public sir


the handler symbol will be evaluated to the value ( symbol — var — value )


one requirement of my system is to be able to trace the request among multiple requests. to accomplish that I’m tracing all the requests that comes in, every endpoints is checking if there is something in the header X-Tracing-Id , otherwise must create one. All the logs into my system must be logged with the traceId on it. to do that tracing part, I’m creating one middleware (defn tracing [handler] … ) that will be responsible for get or create the tracing id. after that I’m assoc into the request.

(defn tracing [{:keys [headers]}]
  (update-in headers [:x-tracing-id] 
             (fnil identity (.toString (java.util.UUID/randomUUID)))))

(defn mw-tracing [handler] 
   (fn [request] 
   (handler (tracing request))) 
that is fine, works great ! my request will be assoced with the tracing-id or a new one. what really bother me is the coupling that I’m building. the request map is containing everything I need, and all my functions are receiving that huge map right now I have * my components ( :db, :aws-clients, :rabbit-mq-client, :redis-client ) ( should the log be a component ? ) * my tracing id * logged user ( if is a logged user or anonymous ) and the list will grow and grow My service layer - or handler layer is receiving the request and destructuring what needs , is the correct way to build clojure systems ? how you guys are building your systems ?


Remember that Clojure favors open data -- so having keys in a map that a particular function ignores is fine. Each function can just destructure the keys it cares about out of the incoming map. If it calls downstream functions that need the map, pass the whole map (so lower-level dependencies can extract whatever they need from the map without intermediate functions caring about those things).


Since the map is immutable and persistent, it's not like you're copying it as you pass it around so there's no performance or memory overhead by having it contain more things (beyond the once-per-request needing to add those things into the request).


I see ! @seancorfield, regarding the log + tracing, how would you handle that ? my logging is a singleton ( ), should I downstream to all my functions the x-tracing-id and use it on my (log/info …) calls ?


I might consider having your tracing middleware create a new key for the tracing id rather than inserting one into the headers map


maybe something like

(defn tracing [{:keys [headers] :as req}]
  (assoc req
         :tracing-id (if (contains? headers :x-tracing-id)
                       (:x-tracing-id headers)
                       (.toString (java.util.UUID/randomUUID)))))


the reasons being 1) middleware or request handlers that want to generically do something with headers will now have a header field that wasn’t part of the actual request


(headers :x-tracing-id (UUID/randomUUID) can replace that if


2) if at some point you want to figure out tracing ids some other way, you can do that transparently


for eg, you want to use headers when someone is logged in, but maybe use GET parameters for testing or something


although, depending on how much your system grows, it may not actually ever matter


@noisesmith, would that create a UUID, regardless of whether you need it?


yes - but that’s relatively cheap


yeah, thanks for the inputs !


also, using namespaced keywords sounds like a neat idea, but I haven’t tried it


about a 10th of an ms


so, we have the request assoced with :x-tracing-id , all my functions ( business logic ) must receive somehow the x-tracing-id because we must logged it. is that the way you build your system ?


if you have an id but it might be brand new, it might make sense to both have the effective id (there whether it’s new or not) and a boolean indicating whether the request had one coming in


Is it considered good practice to catch an exception in a low-level namespace (e.g. Catch unique constraint exception in db namespace) and rethrow it as a custom domain exception (e.g. username-already-taken) that your route handlers can understand and present to the user?


exception/failure is always a recurrent problem to me, no matter language I’m working on. what I like to do is capture the exception on lower level and always returns one “object” that represents the operation Etiher success or Failure. The caller must check if the operation performed properly or not


I’m using dire: to avoid having try-catch blocks all over and also avoid having to check for success/failure of multiple operations


So I would register a handler for my db query function that would catch the PGSQLException and retrow it as a custom exception


my route-handler would have another handler that catches the custom exception and returns a useful error-map to the client


Re: creating the UUID each time, there's always (or (headers "x-tracing-id") (java.util.UUID/randomUUID)) -- and if I'm not mistaken, aren't Ring headers keyed as strings, not keywords?


@oliv the problem with this is there is no general way to prevent all throws, so introducing something other than try/catch means you have two systems to deal with


the only way to have one consistent system for handling failures is to use try/catch and throw


Where you have "expected exceptions" (oh, that there is such a thing!), then it's reasonable to catch them locally and turn them into something else -- but if they're expected then that should flow into regular error handling that you expect to provide to your end users.


Where you have "unexpected exceptions" (where they are truly exceptional) then letting them propagate and logging them at the top level with a "Sorry, an unexpected problem occurred with your request!" end user message is reasonable.


With databases, we've gotten used to relying on constraint violations throwing exceptions when those are often expected failures, not truly exceptions.


It's like throwing an exception on end of file -- of course there's going to be an end of file: that's not exceptional! Hitting EOF before reading a complete/valid form... OK, that might be considered exceptional depending on who controls the file format. (user-supplied, definitely should be expected; system-generated, yeah, throw an exception).


@noisesmith you are right. for that cases I have a global middleware to handle uncaught exceptions. so how you do then ? where are you handling the exceptions ? you have specific handlers for your exceptions ?


my experience with co-workers trying to provide some other systems for handling exceptional but recoverable conditions is that we end up with a multiplicity of success / failure tracking subsystems and the diversity makes it easy to mishandle them, with problems including failing to abort on error states (resulting in garbage or data corruption), hiding of failures so that only downstream symptoms are visible (which makes debugging harder)


Yes! ☝️:skin-tone-2:


The two places to catch an exception are: 1) right at the source if you can do something useful about it 2) right at the top level where you can log it and apologize.


(note: the "source" is defined by module or system boundaries in reality so it moves around a bit)


I’ve literally seen: a) let’s handle this error state by logging an error then moving on b) I’m tired of all this noise in the logs I’m removing the error logging clause c) something is wrong we have no idea what there are no symptoms other than the task failing or returning garbage - when you see the sequence all in one place it’s comical, but as an interaction between code authors it’s an easy state to end up in


also, on some level the correlation between misbehaviors and exception handling is kind of like the correlation between hospitals and mortality - it’s the nature of the thing that a lot of things going wrong are going to interact with your exception handling system, this doesn’t mean the exception handling is at fault


So I should catch the constraint exceptions that are related to my buisness logic at/near-to my query executor function (i.e. duplicate email/username) and let other exceptions unexpected exeptions bubble up to be logged?


That is probably closest to the approach I generally take, yes, @juanjo.lenero