Re: Calling Java from Clojure

2019-06-09 Thread eglue
This is great, Alex, thanks. (Sorry, I deleted from underneath you and 
reposted to fix the title before I saw your reply...)

The latter option, writing interfaces and classes in Java and calling w/ 
the glue code is a great option.

However one big motivator for people moving from Java to langs like Scala 
and Kotlin is being able to implement those bean/record types, eg, with 
such little fanfare & boilerplate (eg in Clojure, using defrecord is so 
concise). And you can sometimes end up with a handful of these, so the 
'glue code' isn't quite so small. Also gen-class and definterface I find 
similarly nice. 

I wonder if there's a path to improve what you're calling option #2. 
Specifically the needing to AOT compile *everything*. It seems I should 
only have to AOT/precompile the surface area that my Java consumer wants to 
link with. At runtime perhaps there'd be some creative way to leave out the 
AOT classes (which would just have been used for static-time compiling) and 
when the JVM tries to load those classes some agent could interject and do 
the dynamic Clojure loading?


On Sunday, June 9, 2019 at 11:21:28 PM UTC-5, Alex Miller wrote:
>
> Looks like the title for this is backwards if I understand the intent, 
> should be calling Clojure from Java, right?
>
> Java code is going to invoke methods on classes (that's all it knows how 
> to do). You have several options:
>
> 1) Use the Clojure Java API to invoke the Clojure runtime - here you're 
> leveraging the Clojure runtime's Java impl core to call into Clojure (Stu's 
> example)
> 2) Use protocols, records, and/or genclass to actually produce Java 
> classes (your example, I think). 
> 3) Define your interface as a set of Java interfaces. Implement this 
> interface in Clojure. You will need a small amount of glue code to provide 
> the API impl (some kind of a factory to give you the impl of the Java 
> interface - either written in Java or using #1). 
>
> #1 is straightforward but tedious - it's really only worthwhile if you 
> have a small amount of this code and hide the use of it.
> #2 has significant downsides - needing to compile everything, all methods 
> are just going to take/return Java Objects, no javadoc on apis,  etc. 
> #3 has advantages in all those areas. You write your Java interface where 
> you can best write it ... in Java (with Javadoc, and Java interfaces, and 
> all the niceties Java users want). IDEs can autocomplete on the Java 
> interfaces. You don't have to AOT - factories can reify or load protocol 
> instances as needed as they return objects. You can even reload internal 
> vars with a connected REPL without restarting the app.
>
> The last does take a bit of planning to set up - you need API code (in 
> Java), and Clojure code that relies on that Java code. lein makes it pretty 
> trivial to put those in one project and compile in that order.
>
> I pushed an example up here:
>
> https://github.com/puredanger/clojure-from-java
>
> It defines a Java interface (java/cfj/Event.java 
> ),
>  
> a static helper to hook the Clojure (java/cfj/Support.java 
> ),
>  
> which uses the Clojure Java API to load the Clojure instance in 
> clj/core/cfj.clj 
> .
>  
> Just `lein uberjar` and you're done. Use the Support API from Java as any 
> other Java class. No AOT required.
>
>
>
> On Sunday, June 9, 2019 at 9:53:56 PM UTC-5, eglue wrote:
>>
>> I've been stalking Clojure for a while but now doing it professionally 
>> full-time (woo hoo!).
>>
>> I saw a Stuart Halloway tweet responding to someone who'd found it a 
>> "soul-crushing, miserable experience."
>>
>> I had a similar miserable experience and figured it was just me, but am 
>> now suspecting that's not the case. (Happy to be shown the light however.)
>>
>> Stuart H posted https://github.com/stuarthalloway/clojure-from-java 
>> 
>>  to 
>> demonstrate the ease of Java consuming Clojure, but I find it far more 
>> important to be able to *compile* Java against Clojure interfaces not 
>> invoke it dynamically from Javabecause dynamic invocation from Java is 
>> unwieldy to the point of it being a likely deal breaker for any Java shop. 
>> Dynamically loading classes and invoking methods c'mon, no one's going 
>> to ask their Java devs to do this.
>>
>> If Clojure doesn't have a good compile-time consumption story for Java 
>> consumers, I think that's a loss. (Even if it is just providing better docs 
>> or archetype/bootstrap examples in this regard.) Because otherwise Java 
>> code bases around the world could be eaten away by (compiled) Clojure from 
>> the inside out, giving Java dev 

Calling Clojure *from* Java

2019-06-09 Thread eglue
Regarding calling Clojure **from** Java...

I saw a Stuart Halloway tweet responding to someone who'd found this a 
"soul-crushing, miserable experience."

I had a similar miserable experience and figured it was just me, but am now 
suspecting that's not the case. (Happy to be shown the light however.)

Stuart H posted https://github.com/stuarthalloway/clojure-from-java to 
demonstrate the ease of Java consuming Clojure, but I find it far more 
important to be able to *compile* Java against Clojure interfaces not 
invoke it dynamically from Javabecause dynamic invocation from Java is 
unwieldy to the point of it being a likely deal breaker for any Java shop. 
Dynamically loading classes and invoking methods c'mon, no one's going 
to ask their Java devs to do this.

If Clojure doesn't have a good compile-time consumption story for Java 
consumers, I think that's a loss. (Even if it is just providing better docs 
or archetype/bootstrap examples in this regard.) Because otherwise Java 
code bases around the world could be eaten away by (compiled) Clojure from 
the inside out, giving Java dev teams enough time to be overtaken by the 
miracle that is Clojure.

Inspired by Stuart's example, I was successful in putting together a quick 
build to achieve this ideal: https://github.com/atdixon/clojure-from-java

However, I have a few open questions:

- when I tried to AOT only the public-facing clojure code that I needed to 
compile against, I found out at runtime that this wasn't going to work. 
Dynamic clojure code was loading my same types into DynamicClassLoader and 
when my statically-compiled, root-class-loaded code was getting executed 
the ClassCastExceptions of course were flying. So am I right to think that 
you have to AOT everything in order to do this right?
- IDE support (for me, Cursive) "works" but is non-ideal; you have to 
manually compile the dependee/Clojure jar, then Cursive will let you 
execute Java code against the manually aot-compiled Clojure code 
- AOT producing generics/generic types doens't seem to be part of any of 
this... is this a lacuna in the Clojure AOT space, are there libs that can 
help here?

This story ^^, if made easier, seems to me would boost Clojure adoption in 
Java/JVM shops.

What am I missing?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/2fcaf22d-2179-4de0-b25b-70ac1b9db58c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Calling Java from Clojure

2019-06-09 Thread eglue
Oops, this should have be titled "Calling Clojure from Java" ... the 
interop with Clojure calling Java is obviously well-worn and solid.

On Sunday, June 9, 2019 at 9:53:56 PM UTC-5, eglue wrote:
>
> I've been stalking Clojure for a while but now doing it professionally 
> full-time (woo hoo!).
>
> I saw a Stuart Halloway tweet responding to someone who'd found it a 
> "soul-crushing, miserable experience."
>
> I had a similar miserable experience and figured it was just me, but am 
> now suspecting that's not the case. (Happy to be shown the light however.)
>
> Stuart H posted https://github.com/stuarthalloway/clojure-from-java to 
> demonstrate the ease of Java consuming Clojure, but I find it far more 
> important to be able to *compile* Java against Clojure interfaces not 
> invoke it dynamically from Javabecause dynamic invocation from Java is 
> unwieldy to the point of it being a likely deal breaker for any Java shop. 
> Dynamically loading classes and invoking methods c'mon, no one's going 
> to ask their Java devs to do this.
>
> If Clojure doesn't have a good compile-time consumption story for Java 
> consumers, I think that's a loss. (Even if it is just providing better docs 
> or archetype/bootstrap examples in this regard.) Because otherwise Java 
> code bases around the world could be eaten away by (compiled) Clojure from 
> the inside out, giving Java dev teams enough time to be overtaken by the 
> miracle that is Clojure.
>
> Inspired by Stuart's example, I was successful in putting together a quick 
> build to achieve this ideal: https://github.com/atdixon/clojure-from-java
>
> However, I have a few open questions:
>
> - when I tried to AOT only the public-facing clojure code that I needed to 
> compile against, I found out at runtime that this wasn't going to work. 
> Dynamic clojure code was loading my same types into DynamicClassLoader and 
> when my statically-compiled, root-class-loaded code was getting executed 
> the ClassCastExceptions of course were flying. So am I right to think that 
> you have to AOT everything in order to do this right?
> - IDE support (for me, Cursive) "works" but is non-ideal; you have to 
> manually compile the dependee/Clojure jar, then Cursive will let you 
> execute Java code against the manually aot-compiled Clojure code 
> - AOT producing generics/generic types doens't seem to be part of any of 
> this... is this a lacuna in the Clojure AOT space, are there libs that can 
> help here?
>
> This story ^^, if made easier, seems to me would boost Clojure adoption in 
> Java/JVM shops.
>
> What am I missing?
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/0e493ca3-b07d-4582-8850-57da5d0132e4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Calling Java from Clojure

2019-06-09 Thread Alex Miller
Looks like the title for this is backwards if I understand the intent, 
should be calling Clojure from Java, right?

Java code is going to invoke methods on classes (that's all it knows how to 
do). You have several options:

1) Use the Clojure Java API to invoke the Clojure runtime - here you're 
leveraging the Clojure runtime's Java impl core to call into Clojure (Stu's 
example)
2) Use protocols, records, and/or genclass to actually produce Java classes 
(your example, I think). 
3) Define your interface as a set of Java interfaces. Implement this 
interface in Clojure. You will need a small amount of glue code to provide 
the API impl (some kind of a factory to give you the impl of the Java 
interface - either written in Java or using #1). 

#1 is straightforward but tedious - it's really only worthwhile if you have 
a small amount of this code and hide the use of it.
#2 has significant downsides - needing to compile everything, all methods 
are just going to take/return Java Objects, no javadoc on apis,  etc. 
#3 has advantages in all those areas. You write your Java interface where 
you can best write it ... in Java (with Javadoc, and Java interfaces, and 
all the niceties Java users want). IDEs can autocomplete on the Java 
interfaces. You don't have to AOT - factories can reify or load protocol 
instances as needed as they return objects. You can even reload internal 
vars with a connected REPL without restarting the app.

The last does take a bit of planning to set up - you need API code (in 
Java), and Clojure code that relies on that Java code. lein makes it pretty 
trivial to put those in one project and compile in that order.

I pushed an example up here:

https://github.com/puredanger/clojure-from-java

It defines a Java interface (java/cfj/Event.java 
),
 
a static helper to hook the Clojure (java/cfj/Support.java 
),
 
which uses the Clojure Java API to load the Clojure instance in 
clj/core/cfj.clj 
. 
Just `lein uberjar` and you're done. Use the Support API from Java as any 
other Java class. No AOT required.



On Sunday, June 9, 2019 at 9:53:56 PM UTC-5, eglue wrote:
>
> I've been stalking Clojure for a while but now doing it professionally 
> full-time (woo hoo!).
>
> I saw a Stuart Halloway tweet responding to someone who'd found it a 
> "soul-crushing, miserable experience."
>
> I had a similar miserable experience and figured it was just me, but am 
> now suspecting that's not the case. (Happy to be shown the light however.)
>
> Stuart H posted https://github.com/stuarthalloway/clojure-from-java 
> 
>  to 
> demonstrate the ease of Java consuming Clojure, but I find it far more 
> important to be able to *compile* Java against Clojure interfaces not 
> invoke it dynamically from Javabecause dynamic invocation from Java is 
> unwieldy to the point of it being a likely deal breaker for any Java shop. 
> Dynamically loading classes and invoking methods c'mon, no one's going 
> to ask their Java devs to do this.
>
> If Clojure doesn't have a good compile-time consumption story for Java 
> consumers, I think that's a loss. (Even if it is just providing better docs 
> or archetype/bootstrap examples in this regard.) Because otherwise Java 
> code bases around the world could be eaten away by (compiled) Clojure from 
> the inside out, giving Java dev teams enough time to be overtaken by the 
> miracle that is Clojure.
>
> Inspired by Stuart's example, I was successful in putting together a quick 
> build to achieve this ideal: https://github.com/atdixon/clojure-from-java 
> 
>
> However, I have a few open questions:
>
> - when I tried to AOT only the public-facing clojure code that I needed to 
> compile against, I found out at runtime that this wasn't going to work. 
> Dynamic clojure code was loading my same types into DynamicClassLoader and 
> when my statically-compiled, root-class-loaded code was getting executed 
> the ClassCastExceptions of course were flying. So am I right to think that 
> you have to AOT everything in order to do this right?
> - IDE support (for me, Cursive) "works" but is non-ideal; you have to 
> manually compile the dependee/Clojure jar, then Cursive will let you 
> execute Java code against the manually aot-compiled Clojure code 
> - AOT producing generics/generic types doens't seem to be part of any of 
> this... is this a lacuna in the Clojure AOT space, are there libs that can 
> help here?
>
> This story ^^, if made easier, seems to me would boost Clojure 

Calling Java from Clojure

2019-06-09 Thread eglue
I've been stalking Clojure for a while but now doing it professionally 
full-time (woo hoo!).

I saw a Stuart Halloway tweet responding to someone who'd found it a 
"soul-crushing, miserable experience."

I had a similar miserable experience and figured it was just me, but am now 
suspecting that's not the case. (Happy to be shown the light however.)

Stuart H posted https://github.com/stuarthalloway/clojure-from-java to 
demonstrate the ease of Java consuming Clojure, but I find it far more 
important to be able to *compile* Java against Clojure interfaces not 
invoke it dynamically from Javabecause dynamic invocation from Java is 
unwieldy to the point of it being a likely deal breaker for any Java shop. 
Dynamically loading classes and invoking methods c'mon, no one's going 
to ask their Java devs to do this.

If Clojure doesn't have a good compile-time consumption story for Java 
consumers, I think that's a loss. (Even if it is just providing better docs 
or archetype/bootstrap examples in this regard.) Because otherwise Java 
code bases around the world could be eaten away by (compiled) Clojure from 
the inside out, giving Java dev teams enough time to be overtaken by the 
miracle that is Clojure.

Inspired by Stuart's example, I was successful in putting together a quick 
build to achieve this ideal: https://github.com/atdixon/clojure-from-java

However, I have a few open questions:

- when I tried to AOT only the public-facing clojure code that I needed to 
compile against, I found out at runtime that this wasn't going to work. 
Dynamic clojure code was loading my same types into DynamicClassLoader and 
when my statically-compiled, root-class-loaded code was getting executed 
the ClassCastExceptions of course were flying. So am I right to think that 
you have to AOT everything in order to do this right?
- IDE support (for me, Cursive) "works" but is non-ideal; you have to 
manually compile the dependee/Clojure jar, then Cursive will let you 
execute Java code against the manually aot-compiled Clojure code 
- AOT producing generics/generic types doens't seem to be part of any of 
this... is this a lacuna in the Clojure AOT space, are there libs that can 
help here?

This story ^^, if made easier, seems to me would boost Clojure adoption in 
Java/JVM shops.

What am I missing?


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/2d16d197-dff5-4417-9ea7-d85e4baa00a6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: spec error output in web context

2019-06-09 Thread 'Sven Richter' via Clojure


Am Sonntag, 9. Juni 2019 16:15:38 UTC+2 schrieb Alex Miller:
>
>
>
> On Sun, Jun 9, 2019 at 8:43 AM 'Sven Richter' via Clojure <
> clo...@googlegroups.com > wrote:
>
>>
>> I also tried to catch the exception and *(-> ex Throwable->map 
>> clojure.main/ex-triage clojure.main/ex-str) *as you suggested, which 
>> works. But like I said, I would not want to check for exceptions during 
>> production that are only thrown during development. 
>>
>
> The generic question here is "what happens when my web request handler 
> throws an unexpected exception?" An exception can be thrown in either dev 
> or prod. "spec" errors are not special in this regard. Yes, you happen to 
> be doing some extra checking in dev, but in either case you want to 
> properly handle exceptions. The error handling chain above will give you 
> better output for all exceptions, not just spec.
>  
>
 I would like to respectfully disagree here. The docs explicitly state that 
it is not advised to use *instrument* in production. So in production I 
will never see the same error messages regarding spec as in development, at 
least regarding to *fdef*. So what is a useful exception during development 
with a useful output in production it might become visible just a few 
functions down the stack becoming a NullpointerException, for instance. 
This is especially true in cases like my one, when I consume a third-party 
web service where the interface is prone to change.


>> Do you know of a different way? Maybe a middleware would be feasible that 
>> is only added during development? 
>>
>
> The question of how to handle exceptions in immutant is an immutant 
> question. If you read the docstring of immutant.web/run, it tells you how 
> to do it for ring handlers:
>
>For ring handlers, the actual writing of the response happens after
>your hander returns. If an exception occurs on the write (the most
>common case being an IOException because the client has gone away),
>the default behavior is to log the exception. 
>
> *If you would like to   be able to handle that exception yourself, you can 
> return a function   in the ring response under :write-error-handler.* 
> This function will
>be called with the exception, the request map, and the response map
>if an exception occurs when writing the response. Note that this
>handler can't actually affect the response. 
> *If you would prefer   a global handler, see 
> immutant.web.middleware/wrap-write-error-handling*.
>

I should have looked up the immutant docs myself. Unfortunately I was 
totally unaware of the different possible outcomes of spec errors. 

Anyway, thank you very much again for your explanations, I think I got it 
all together now and learned something new today :-)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/9a930376-1bb8-480e-bda1-c834a9bd421e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: spec error output in web context

2019-06-09 Thread Alex Miller
On Sun, Jun 9, 2019 at 8:43 AM 'Sven Richter' via Clojure <
clojure@googlegroups.com> wrote:

> Hi Alex,
>
> I tracked it down to a minimal example with an explanation here:
> https://gist.github.com/sveri/1aaad9b12a8ec90d243206ab3b6073e3
>
> The short version is. Running a specced function in the clj repl will
> produce meaningful output, while running in the web context with immutant
> will print a stacktrace with the ExceptionInfo exception.
>
> I also tried to catch the exception and *(-> ex Throwable->map
> clojure.main/ex-triage clojure.main/ex-str) *as you suggested, which
> works. But like I said, I would not want to check for exceptions during
> production that are only thrown during development.
>

The generic question here is "what happens when my web request handler
throws an unexpected exception?" An exception can be thrown in either dev
or prod. "spec" errors are not special in this regard. Yes, you happen to
be doing some extra checking in dev, but in either case you want to
properly handle exceptions. The error handling chain above will give you
better output for all exceptions, not just spec.


>
> Do you know of a different way? Maybe a middleware would be feasible that
> is only added during development?
>

The question of how to handle exceptions in immutant is an immutant
question. If you read the docstring of immutant.web/run, it tells you how
to do it for ring handlers:

   For ring handlers, the actual writing of the response happens after
   your hander returns. If an exception occurs on the write (the most
   common case being an IOException because the client has gone away),
   the default behavior is to log the exception.

*If you would like to   be able to handle that exception yourself, you can
return a function   in the ring response under :write-error-handler.* This
function will
   be called with the exception, the request map, and the response map
   if an exception occurs when writing the response. Note that this
   handler can't actually affect the response.
*If you would prefer   a global handler, see
immutant.web.middleware/wrap-write-error-handling*.

It might be a reasonable improvement to immutant to do this better error
printing by default (with the caveat that you have to be on Clojure 1.10 to
do so).


> What does the clj repl do to produce that output?
>

It catches exceptions during the read, eval, and print phases and calls
(-> ex Throwable->map clojure.main/ex-triage clojure.main/ex-str)


> Thank you for your time,
> Sven
>
> Am Samstag, 8. Juni 2019 20:52:27 UTC+2 schrieb Alex Miller:
>>
>>
>>
>> On Saturday, June 8, 2019 at 1:41:59 AM UTC-5, Sven Richter wrote:
>>>
>>>
>>>
>>> Am Freitag, 7. Juni 2019 15:35:41 UTC+2 schrieb Alex Miller:

 How do you start the web server?

>>> I use component to startup immutant web, I also tried with http-kit, but
>>> that didnt make a difference.
>>>
>>
>> What I mean is, what command do you use? Are using "lein ring server" or
>> something like that?
>>
>>
>>>
>>> Who is printing the error?

>>> I think thats the key point here, right now I dont know as I never
>>> bothered to figure out who prints the stacktraces.
>>>
>>
>> I don't think you're going to be able to improve this without
>> understanding the answer to that question.
>>
>>
>>>
>>>
 There are functions available in clojure.main to replicate the message
 from the repl - you can call them yourself.

 See https://clojure.org/reference/repl_and_main#_error_printing for
 more on error triage and the functions like Throwable>map,
 clojure.main/ex-triage, and clojure.main/ex-str. This chain of functions is
 what the REPL uses to produce the message below

>>>
>>>
>>> Thanks, I will try that, but that would mean I will have to catch every
>>> potential ExceptionInfo error and check if its a spec error which is pretty
>>> cumbersome, especially as I only want to see these outputs during
>>> development (instrument is turned off in production).
>>>
>>
>> The triage process knows how to print a good message for any error, not
>> just a spec instrumentation error. There shouldn't be any conditional
>> needed.
>>
>>
>>>
>>> Thanks,
>>>
>>> Sven
>>>
>>> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/RKb6XOjCK8A/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> To view this discussion 

Re: spec error output in web context

2019-06-09 Thread 'Sven Richter' via Clojure
Hi Alex,

I tracked it down to a minimal example with an explanation here: 
https://gist.github.com/sveri/1aaad9b12a8ec90d243206ab3b6073e3

The short version is. Running a specced function in the clj repl will 
produce meaningful output, while running in the web context with immutant 
will print a stacktrace with the ExceptionInfo exception.

I also tried to catch the exception and *(-> ex Throwable->map 
clojure.main/ex-triage clojure.main/ex-str) *as you suggested, which works. 
But like I said, I would not want to check for exceptions during production 
that 
are only thrown during development. 

Do you know of a different way? Maybe a middleware would be feasible that 
is only added during development? What does the clj repl do to produce that 
output?

Thank you for your time,
Sven

Am Samstag, 8. Juni 2019 20:52:27 UTC+2 schrieb Alex Miller:
>
>
>
> On Saturday, June 8, 2019 at 1:41:59 AM UTC-5, Sven Richter wrote:
>>
>>
>>
>> Am Freitag, 7. Juni 2019 15:35:41 UTC+2 schrieb Alex Miller:
>>>
>>> How do you start the web server?
>>>
>> I use component to startup immutant web, I also tried with http-kit, but 
>> that didnt make a difference.
>>
>
> What I mean is, what command do you use? Are using "lein ring server" or 
> something like that?
>  
>
>>
>> Who is printing the error?
>>>
>> I think thats the key point here, right now I dont know as I never 
>> bothered to figure out who prints the stacktraces.
>>
>
> I don't think you're going to be able to improve this without 
> understanding the answer to that question. 
>  
>
>>
>>
>>> There are functions available in clojure.main to replicate the message 
>>> from the repl - you can call them yourself.
>>>  
>>> See https://clojure.org/reference/repl_and_main#_error_printing for 
>>> more on error triage and the functions like Throwable>map, 
>>> clojure.main/ex-triage, and clojure.main/ex-str. This chain of functions is 
>>> what the REPL uses to produce the message below
>>>
>>
>>
>> Thanks, I will try that, but that would mean I will have to catch every 
>> potential ExceptionInfo error and check if its a spec error which is pretty 
>> cumbersome, especially as I only want to see these outputs during 
>> development (instrument is turned off in production).
>>
>
> The triage process knows how to print a good message for any error, not 
> just a spec instrumentation error. There shouldn't be any conditional 
> needed.
>  
>
>>
>> Thanks,
>>
>> Sven
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/d667e44b-397f-4a34-9c95-a0ab9adc4f54%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.