2

I'm writing a user script and I want to hit the SE API for something, but SE.init is failing without much feedback indicating what the issue is. According to the documentation, it should be initialized like this:

SE.init({
    clientId: 1,
    key: '123456',
    channelUrl: 'http://example.com/blank',
    complete: function (data) { ... }
});

Further down the same page in the example, it looks like this:

SE.init({ 
    // Parameters obtained by registering an app, these are specific to the SE
    //   documentation site
    clientId: 1, 
    key: 'U4DMV*8nvpm3EOpvf69Rxw((', 
    // Used for cross domain communication, it will be validated
    channelUrl: 'https://api.stackexchange.com/docs/proxy',
    // Called when all initialization is finished
    complete: function(data) { 
        $('#login-button')
            .removeAttr('disabled')
            .text('Run Example With Version '+data.version); 
    }
});

Here is what I'm doing (in a user script):

SE.init({
    clientId: 1685,
    key: "lHi*7B5IMDmzKmssD34nkQ((",
    channelUrl: sprintf('https://%s/about', window.location.host),
    complete: function(data) {
        debug("SE API version " + data.version);
    }
});

I've also tried with various values for both key and channelUrl. In all cases, this produces the following explosion in the js console:

env: ERROR: Syntax error @ 'StackTrello'!
##########################
// ==UserScript==
// ... userscript stuff
// ==/UserScript==
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
var log_levels = { trace: 5, debug: 4, info: 3, warn: 2, err: 1, off: 0 };
var log_level = log_levels.trace;

var se_client_id = 1685;
var se_api_key = 'lHi*7B5IMDmzKmssD34nkQ((';

GM_log(sprintf("loaded v%s with jquery %s",
               GM_info.script.version,$.fn.jquery));

function trace(msg) {if (log_level > log_levels.trace) GM_log(sprintf('trace: %s', msg));}
function debug(msg) {if (log_level > log_levels.debug) GM_log(sprintf('debug: %s', msg));}
function info(msg) {if (log_level > log_levels.info) GM_log(sprintf('info: %s', msg));}
function warn(msg) {if (log_level > log_levels.warn) GM_log(sprintf('warn: %s', msg));}
function err(msg) {if (log_level > log_levels.err) GM_log(sprintf('err: %s', msg));}

SE.init({
    clientId: 1685,
    key: "lHi*7B5IMDmzKmssD34nkQ((",
    channelUrl: sprintf('https://%s/about', window.location.host),
    complete: function(data) {
        debug("SE API version " + data.version);
    }
});
##########################
ERROR: Cannot call method 'replace' of undefined
TypeError: Cannot call method 'replace' of undefined

at Function.eval (eval at <anonymous> (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54)), <anonymous>:420:22)
at Function.eval (eval at <anonymous> (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54)), <anonymous>:422:4)
at ah (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54), <anonymous>:204:4)
at M (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54), <anonymous>:205:7)
at n (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54), <anonymous>:443:2)
at X (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54), <anonymous>:447:85)
at T (eval at <anonymous> (http://meta.stackoverflow.com/questions/185078/have-history-registered-in-browser-with-user-search-results:67:54), <anonymous>:242:40)

Update

I boiled down my script to the simplest possible way to reproduce the error. Here is the whole thing:

// ==UserScript==
// @name        StackTrello
// @author      Benjamin Collins <[email protected]>
// @namespace   https://gist.github.com/aggieben
// @version     0.0.1
// @description Script to render a link that will create a new trello card from a StackExchange site post
// @match       *://*.stackoverflow.com/q*
// @run-at      document-end
// @copyright   2013+, Benjamin Collins
// @require     https://api.stackexchange.com/js/2.0/all.js
// ==/UserScript==
// Settings for users to modify

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

SE.init(null);

The very first thing that happens in the init function is to throw an exception if the parameter is falsey:

init:function(d){if(!d)throw"must pass an object";

it doesn't even get there.

3
  • Are you using Tampermonkey? Do you have @grant directives for the GM_ objects/functions? This looks like it might be a sandbox/scope issue. We might need to see the complete script. If using Tampermonkey, try it on FF+GM. It should either work or fail in a different way. Jun 19, 2013 at 22:24
  • Yep, this is TM 3.2.3444, and I don't have any @grant directives. I'll give FF a try. Jun 19, 2013 at 22:28
  • @BrockAdams I've updated my example above to show the entire script, which you can see does not use any GM_* functions (or any functions at all except for SE.init). Jun 20, 2013 at 16:47

1 Answer 1

2

Alrighty - I found the issue. Tampermonkey assumes that any exception thrown from a user script is an Error object (well...it assumes the exception data will have at least the message and stack properties). When it tries to do string operations on undefined properties, it throws its own exception which makes the whole thing blow up.

The Javascript SDK throws strings, so unless everything works perfectly from the get-go, your script will be hosed. This is a Tampermonkey problem, so I opened issue 153 (and attached a patch with the fix) on the Tampermonkey Google Code site.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .