ToolJet/ToolJet · error · QueryError

Could not connect to Googles Calendar

Error message

Could not connect to Googles Calendar

What it means

The outer catch in refreshToken() re-wraps any error thrown inside the try as QueryError('Could not connect to Googles Calendar', ...) (note the typo 'Googles'). Because errors 144 and 145 are thrown inside the same try, this catch will re-wrap them — so callers may see this message even when the actual cause was a missing access_token or a 4xx. The description is JSON.stringify of error.response?.statusCode and error.response?.body, but note: QueryError is an Error subclass without a .response property, so when the inner thrown value is itself a QueryError, error.response is undefined and the description becomes '{"statusCode":undefined,"message":undefined}'.

Source

Thrown at marketplace/plugins/googlecalendar/lib/index.ts:313

      if (result['access_token']) {
        accessTokenDetails['access_token'] = result['access_token'];
        accessTokenDetails['refresh_token'] = result['refresh_token'];
      } else {
        throw new QueryError(
          'access_token not found in the response',
          {},
          {
            responseObject: {
              statusCode: response.statusCode,
              responseBody: response.body,
            },
            responseHeaders: response.headers,
          }
        );
      }
    } catch (error) {
      throw new QueryError(
        'Could not connect to Googles Calendar',
        JSON.stringify({ statusCode: error.response?.statusCode, message: error.response?.body }),
        {}
      );
    }
    return accessTokenDetails;
  }
}

View on GitHub (pinned to 20602a8e10)

Solutions

  1. Re-throw QueryError instances unchanged instead of re-wrapping: `if (err instanceof QueryError) throw err;` at the top of the catch.
  2. When constructing the description, read from the got HTTPError shape (error.response) only when present; otherwise fall back to err.message or err.description.
  3. Fix the typo 'Googles' -> 'Google\'s' for log searchability.
  4. Inspect err.name/err.constructor.name in the caller to recover the original QueryError if you cannot patch the plugin.

Example fix

// before — blindly re-wraps, destroys inner cause, has typo
} catch (error) {
  throw new QueryError(
    'Could not connect to Googles Calendar',
    JSON.stringify({ statusCode: error.response?.statusCode, message: error.response?.body }),
    {}
  );
}

// after — preserve inner QueryError, sensible description
} catch (error) {
  if (error instanceof QueryError) throw error;
  throw new QueryError(
    "Could not connect to Google's Calendar",
    JSON.stringify({ statusCode: error.response?.statusCode, message: error.response?.body }),
    {}
  );
}
Defensive patterns

Strategy: try-catch

Type guard

function isGoogleCalendarConnectError(e): boolean {
  return e?.name === 'QueryError'
      && /Could not connect to Googles? Calendar/.test(e?.message ?? '');
}

Try / catch

try {
  await cal.refreshToken(sourceOptions);
} catch (e) {
  // The outer catch destroys the inner cause; recover what we can from description:
  let parsed = {};
  try { parsed = JSON.parse(e.description ?? '{}'); } catch {}
  if (parsed.statusCode === undefined && parsed.message === undefined) {
    // likely a re-wrapped QueryError (144/145); surface original via patching the plugin
  }
  throw e;
}

Prevention

When it happens

Trigger: Any thrown error inside the token-exchange try block: got() network/HTTP error (has .response), or the explicitly-thrown QueryErrors from 144/145 (no .response → unhelpful description). Also fires on JSON.parse failure of the response body.

Common situations: Token-exchange endpoint unreachable; Google returned non-JSON; the inner code threw a QueryError which is then mis-wrapped here, hiding the real cause; downstream caller logs only the description string and sees a useless '{statusCode:undefined,message:undefined}'.

Related errors


AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13). Data as JSON: /api/errors/e1994dab90e96cf3. Report an issue: GitHub.