Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Show alert if ajax call succeeds but the returned javascript fails #1364

Closed
wants to merge 2 commits into from

5 participants

@jeppenejsum
Owner

Only when running in DevMode.

Have not really tested with anything but JQuery artifacts, but have included some basic sanity checks on the parameters.

@Shadowfiend
Owner

Do these errors not show up on the console? Alert boxes are really annoying if you're used to using dev tools, and as I recall parse errors in returned JS are listed on the dev console.

@pbrant
Collaborator
@andreak
Owner
@andreak
Owner
@Shadowfiend
Owner

That's odd, but I may remember something like that being the case, yeah. In that case, let me suggest this instead of a straight alert:

(typeof console == "undefined" ? alert : console.error)(/* ... message ... */)

This way we use the console error logging mechanism if it's available. Alerts are annoying for more than just their interruption quality: they're also completely non-interactable (e.g., to go find line numbers), their sizing doesn't accommodate longer messages well, and most browsers don't let you copy/paste out of them. Plus you have to dismiss them if you want to look at other debug info (e.g., to reference the server response).

@jeppenejsum
Owner

The errors are not shown in the console (at least not on FF & safari). Alerts are annoying but I don't think we have a better solution in place today (except to test for console etc)

But the alternative today is also an alert (but not until after the request has been tried 3 times, presumably with the same invalid javascript being returned each time :-)

@Shadowfiend
Owner

Nope, clever though it is, my solution won't work. We need to be more explicit:

var error = "... message ...";
if (console && typeof console.error == 'function')
  console.error(message);
else
  alert(message);
@Shadowfiend
Owner

Also, the new retry code should hopefully not run the request 3 times server-side anymore, so you should just get it as soon as the computation wraps up on the server, as both retries will return their result immediately.

@jeppenejsum
Owner

Ok makes sense. I think I'll add a lift_logError method to liftAjax, it might come in handy in other situations.

@Shadowfiend
Owner

Props for an even better solution. Then anyone can customize their error handling client-side. I did some similar things for handling comet errors and such.

@jeppenejsum jeppenejsum Added lift_logError to liftAjax and made the actual logging method co…
…nfigurable using LiftRules.

Now defaults to using the javascript console if available or alert otherwise
218d8a1
@fmpwizard
Owner

rebased into master

@fmpwizard fmpwizard closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 20, 2012
  1. @jeppenejsum
Commits on Nov 21, 2012
  1. @jeppenejsum

    Added lift_logError to liftAjax and made the actual logging method co…

    jeppenejsum authored
    …nfigurable using LiftRules.
    
    Now defaults to using the javascript console if available or alert otherwise
This page is out of date. Refresh to see the latest.
View
16 web/webkit/src/main/scala/net/liftweb/http/LiftRules.scala
@@ -754,6 +754,22 @@ class LiftRules() extends Factory with FormVendor with LazyLoggable {
r.isIE8) openOr true
/**
+ * The JavaScript to execute to log a message on the client side when
+ * liftAjax.lift_logError is called.
+ *
+ * If Empty no logging is performed
+ * The default when running in DevMode is to call lift_defaultLogError which
+ * will use JavaScript console if available or alert otherwise.
+ *
+ * To always use alert set:
+ *
+ * LiftRules.jsLogFunc = Full(v => JE.Call("alert",v).cmd)
+ */
+ @volatile var jsLogFunc: Box[JsVar => JsCmd] =
+ if (Props.devMode) Full(v => JE.Call("liftAjax.lift_defaultLogError", v))
+ else Empty
+
+ /**
* The JavaScript to execute at the end of an
* Ajax request (for example, removing the spinning working thingy)
*/
View
25 web/webkit/src/main/scala/net/liftweb/http/js/ScriptRenderer.scala
@@ -20,6 +20,8 @@ package js
import net.liftweb.http._
import net.liftweb.common._
+import net.liftweb.util.Props
+import net.liftweb.http.js.JE.JsVar
/**
* the default mechanisms for doing Ajax and Comet in Lift
@@ -69,6 +71,17 @@ object ScriptRenderer {
lift_uriSuffix: undefined,
+ lift_logError: function(msg) {
+ """ + (LiftRules.jsLogFunc.map(_(JsVar("msg")).toJsCmd) openOr "") + """
+ },
+
+ lift_defaultLogError: function(msg) {
+ if (console && typeof console.error == 'function')
+ console.error(msg);
+ else
+ alert(msg);
+ },
+
lift_ajaxQueueSort: function() {
liftAjax.lift_ajaxQueue.sort(function (a, b) {return a.when - b.when;});
},
@@ -150,9 +163,17 @@ object ScriptRenderer {
var failureFunc = function() {
liftAjax.lift_ajaxInProcess = null;
- var cnt = aboutToSend.retryCnt;
+ var cnt = aboutToSend.retryCnt;""" +
+ (if (!Props.devMode) "" else
+ """
+ if (arguments.length == 3 && arguments[1] == 'parsererror') {
+ liftAjax.lift_logError('The server call succeeded, but the returned Javascript contains an error: '+arguments[2])
+ } else
+ """) +
+
+ """
if (cnt < liftAjax.lift_ajaxRetryCount) {
- aboutToSend.retryCnt = cnt + 1;
+ aboutToSend.retryCnt = cnt + 1;
var now = (new Date()).getTime();
aboutToSend.when = now + (1000 * Math.pow(2, cnt));
queue.push(aboutToSend);
Something went wrong with that request. Please try again.