Fork me on GitHub
#fulcro
<
2022-01-11
>
Dean Hayes10:01:17

Hi everyone. We have a Fulcro app which is using a state machine for sign in. It's all working well, but I've noticed that if the server side mutation throws an exception (in this case, as part of a test) on the front end I get two errors reported in the console. The first one is saying the server returns a 500 (fair enough) but the second one is complaining that String isn't associative, which is obviously isn't:

[com.fulcrologic.fulcro.algorithms.merge:163] - Unable to mark missing on result. Returning unmarked result. See 
Error: No protocol method IAssociative.-assoc defined for type string
The response string is being sent from the https://github.com/fulcrologic/fulcro/blob/develop/src/main/com/fulcrologic/fulcro/server/api_middleware.clj#L75 fn which returns a String in the case of an error ("Internal server error. Parser threw an exception. See server logs for details."). In this failing case the content type of the response header is application/octet-stream which doesn't seem right? I've tried modifying handle-api-request so the content type is text/plain which sounds more like it, but this gives the same result in the front end. If I change the response to be a map (eg {:error "Internal server error. Parser threw an exception. See server logs for details."}) I don't see this second associative error. Should the Fulcro response be a map? This code hasn't changed for 3 years which makes me think it's probably fine and we've done something wrong either in the front end or the server side code... but I'm not sure where to look. If anyone has any suggestions that would be much appreciated, cheers :)

hadils13:01:20

I have this exact problem when refreshing JWTs.

tony.kay17:01:07

There are several parts that interact here. Unfortunately I never had the time to tune the template to be perfect on error handling, so it may be a bit out of whack (if that’s what you based on). The server response expected from the API is always a map, but an exception can cause that to not be true, which in turn can cause the response to NOT be encoded as transit+json. So, step 1 is to ensure that your server is always returning transit+json responses, OR you have to deal with it in the next layer (the http remote in the client). The client remote gets the raw response. For some server errors it is impossible to actually have it be transit encoded, and you just have to do something else. This is where the response middleware comes into play. It is the layer the decodes the transit and has expectations about the response content. What you do with errors in you app can be tuned here as well. For example you could pop up UI toasts or even have an atom holding the Fulcro app that allows you to transact something as you circumvent the response decoding.

Dean Hayes13:01:37

Hi Tony and Jakub, Thanks both very much for your replies, much appreciated. To your point, Tony... > So, step 1 is to ensure that your server is always returning transit+json responses The bit of code that's returning a String under error circumstances is within Fulcro (as I mentioned above - com.fulcrologic.fulcro.server.api-middleware/handle-api-request). As I said if I modify that to return a map (with the error message in it) that does fix the problem. It's not worth updating that function to return a map, is it? Or do we need to be mindful of changing the behaviour and therefore it's better not to change it? If that's the case would another fn be worth adding and deprecating the old one? I'm happy to create a PR if you think that's useful, but obivoiulsy just say if not (I can just create a version locally for our needs, no problem) Thanks again both for your help!

tony.kay16:01:54

Ah, hm. Yes, that is a bit of an oversight on my part, but it has been that way for a long time, so it is possible someone’s network stack relies on it. Thus, changing it would be a breaking change. The options are: 1. Create a handle-api-request2 that returns a map 2. Make the current one more configurable somehow 3. Do nothing and let others fix it as they see fit

tony.kay16:01:46

How about adding an arity. The new argument would be a function that transforms exceptions into responses. That would be a non-breaking change, and would let you configure it as you see fit.

tony.kay16:01:25

If you’re interested in doing that PR, updating the docstring, and updating the relevant section of the dev guide it would be much appreciated.

Dean Hayes16:01:30

Great - an extra arg sounds like a good idea, thanks. I'll create a PR with all the associated bits, no worries. Might take a day or two to get to it, but that would be nice to do. Cheers :)

tony.kay21:01:13

cool, thanks