借助 Looker 扩展程序框架,您可以构建在 Looker 中运行的自定义 JavaScript 和 TypeScript 应用和可视化图表。扩展程序在沙盒化 iframe 中运行,并通过扩展程序 SDK 与 Looker 实例进行交互。如果您在使用自定义扩展程序时遇到问题,例如 iframe 内出现空白页面或错误消息、浏览器控制台 JavaScript 或跨域资源共享 (CORS) 错误、Looker API 请求失败(4xx 或 5xx 状态代码)或 manifest.lkml 配置错误,本文档可帮助您排查并解决这些问题。
前提条件和常见配置要求
在开始问题排查之前,请验证您的环境、LookML 项目和用户账号是否满足运行 Looker 扩展程序的要求:
- 已启用扩展程序框架:Looker 管理员必须在管理 > 平台 > 扩展程序框架下启用扩展程序框架设置。
- LookML 项目和模型配置:每个扩展程序都需要一个 LookML 项目,其中包含以下组件:
- 配置了有效
connection参数的模型文件。 - 包含
application声明的项目清单文件 (manifest.lkml)。 - 已配置的 Git 连接。
- 配置了有效
- 清单授权:
manifest.lkml文件中的application声明必须明确定义扩展程序所需的所有entitlements,例如用于 Looker API 调用的core_api_methods或用于向外部网域发出请求的external_api_urls。如果没有entitlements代码块,扩展程序将无法运行。 - 用户权限:用户必须拥有包含扩展程序 LookML 模型的模型集的扩展程序权限(例如
access_data、explore或develop)。如需构建扩展程序,开发者需要拥有 LookMLdevelop权限。 - 诊断工具和环境详细信息:在开始问题排查之前,请准备好以下详细信息和工具:
- 您的 Looker 实例网址、LookML 项目名称以及在
manifest.lkml中声明的application名称。 - 在客户端机器上访问网络浏览器的开发者工具(控制台和网络标签页)。
- 在本地开发期间,访问运行本地开发服务器的终端。
- 对于 Looker API 调用中的
5xx服务器错误,需要访问 Looker 实例日志(客户托管实例上的looker.log,或 Google Cloud 控制台中 Looker (Google Cloud Core) 实例的 Cloud Logging 中的 Logs Explorer)。
- 您的 Looker 实例网址、LookML 项目名称以及在
调试树
使用以下决策树开始排查 Looker 扩展程序框架问题:
以下部分将更详细地介绍树中的场景。
检查浏览器控制台和网络日志
由于 Looker 扩展程序在浏览器中运行,因此请先检查浏览器的开发者工具,查看是否存在 JavaScript 错误、违反安全政策的情况以及失败的 HTTP 请求,以便开始排查问题。
检查浏览器控制台是否存在错误
如需识别导致扩展程序无法加载或运行的客户端错误,请执行以下操作:
- 在 Looker 中,打开加载扩展程序的页面。
- 右键点击页面上的任意位置,然后选择检查(或在 Windows 和 Linux 上按 Control+Shift+I,在 macOS 上按 Command+Option+I)。
- 在开发者工具面板中,选择控制台标签页。
- 刷新页面以捕获初始加载期间发生的错误。
- 检查控制台中的所有红色出错提示:
- JavaScript 运行时错误(例如
Uncaught TypeError或ReferenceError):请记下堆栈轨迹中的文件和行号,然后参阅排查运行时 JavaScript 和逻辑错误。 401 Unauthorized或403 Forbidden错误:表示身份验证或权限问题。请参阅排查身份验证和 API 访问问题。404 Not Found错误:表示找不到扩展程序的 JavaScript 软件包或请求的资源。验证您的清单配置和本地开发服务器。- CORS 或内容安全政策 (CSP) 错误:表示浏览器屏蔽了跨域请求或资源。请参阅排查网络、CORS 和安全政策问题。
- JavaScript 运行时错误(例如
检查“网络”标签页中是否有失败的请求
如需分析扩展程序针对 JavaScript 软件包、资源或 API 端点发出的 HTTP 请求,请按以下步骤操作:
- 在浏览器开发者工具面板中,选择网络标签页。
- 选中停用缓存复选框,以便浏览器不会加载过时的缓存资源。
- 刷新加载了该扩展程序的页面。
- 检查网络请求列表,看看是否有任何
4xx或5xx状态代码,然后选择失败的请求,检查其标头、载荷和响应标签页:404扩展程序软件包(例如bundle.js):验证开发服务器是否正在运行,以及manifest.lkml中的url或file参数是否准确。- Looker API 请求返回
401或403:调查身份验证、权限和授权。 - API 请求中的
400或422:检查载荷和响应标签页,找出格式错误的 JSON 或无效的请求参数。 5xx服务器错误:表示 Looker 实例上存在服务器端错误。在客户托管实例上检查looker.log,或在控制台中检查 Looker (Google Cloud Core)实例的 Logs Explorer,以查找具有匹配时间戳的条目。
如果控制台或网络标签页中未显示任何错误,或者您需要验证 Looker 如何加载扩展程序,请继续执行下一部分。
验证清单和项目配置
项目 manifest.lkml 文件中的 application 声明控制 Looker 如何加载扩展程序以及扩展程序可以使用哪些资源。manifest.lkml 中的配置错误是导致加载和 API 失败的常见原因:
- 验证
url或file参数:在 Looker IDE 中,打开项目的manifest.lkml文件并检查application声明: - 验证
manifest.lkml授权:查看application声明中的entitlements块。除非明确声明了该授权,否则扩展程序无法使用 Looker 资源或外部网域,如下所示:core_api_methods:必须列出 扩展程序调用 的每个 Looker API 方法(例如core_api_methods: ["me", "all_looks", "run_inline_query"])。external_api_urls:必须列出扩展程序直接或通过代理请求的所有外部非 Looker 网域。- 其他权限:验证您的扩展程序是否需要
local_storage、navigation、new_window、new_window_external_urls、use_form_submit、use_embeds、use_downloads、use_iframes、use_clipboard、oauth2_urls、global_user_attributes或scoped_user_attributes。
- 验证、提交和部署:修改
manifest.lkml后,点击验证 LookML,提交更改,然后点击部署到生产环境,使更新后的配置生效。
排查本地开发服务器和环境问题
在本地开发扩展程序时,如果您在 manifest.lkml 中使用 url 参数,则本地开发服务器必须正在运行,并且可从浏览器访问:
- 确认开发服务器正在运行:检查您启动开发服务器的终端窗口(例如,使用
yarn develop或npm start):- 验证构建是否已编译且没有错误,并显示监听消息(例如
webpack compiled successfully或listening on localhost:8080)。 - 如果服务器未运行,请使用
yarn develop或npm start启动它。 - 如果服务器因语法错误或缺少依赖项错误而退出,请解决代码错误或运行
yarn install(或npm install)以安装缺少的软件包。 - 如果服务器因端口冲突 (
EADDRINUSE) 而失败,请停止使用该端口的其他进程,或将开发服务器和manifest.lkmlurl参数配置为使用其他端口。
- 验证构建是否已编译且没有错误,并显示监听消息(例如
- 直接在浏览器中打开扩展程序网址:从
manifest.lkml复制url值(例如https://localhost:8080/bundle.js),然后在新的浏览器标签页中打开该值:- 不受信任的自签名 SSL 证书:本地开发服务器经常使用自签名 SSL 证书。如果浏览器显示证书安全警告,请选择高级,然后继续前往
localhost,以便在浏览器会话中信任该证书。在证书受信任之前,浏览器会阻止该软件包在 Lookeriframe中加载。 - 连接被拒或被阻止:如果浏览器无法访问该网址,请验证是否有本地防火墙或端点安全软件阻止在配置端口上连接到
localhost。
- 不受信任的自签名 SSL 证书:本地开发服务器经常使用自签名 SSL 证书。如果浏览器显示证书安全警告,请选择高级,然后继续前往
排查网络、CORS 和安全政策问题
网络浏览器会强制执行同源政策,这会阻止 Looker 加载扩展程序资源或调用其他来源的外部服务器,除非配置了跨域资源共享 (CORS) 标头和安全政策:
- 在浏览器控制台中识别 CORS 错误:在控制台标签页中查找包含
Cross-Origin Resource Sharing、CORS、has been blocked by CORS policy或缺少Access-Control-Allow-Origin标头的错误消息。 - 配置本地开发服务器 CORS 标头:如果您使用
webpack-dev-server(或类似的打包工具),请确保webpack.config.js中的devServer配置包含Access-Control-Allow-Origin标头:javascript devServer: { headers: { "Access-Control-Allow-Origin": "*" } } - 配置生产托管和外部 API CORS 标头:如果您的扩展程序从外部服务(例如 Cloud Storage、Amazon S3 或自定义后端服务器)加载资源或请求数据,请将托管服务配置为返回允许 Looker 实例网域的
Access-Control-Allow-Origin标头。此外,请验证没有网络代理或防火墙从响应中剥离 CORS 标头,并确保外部网域在manifest.lkml的external_api_urls中列出。 - 检查内容安全政策 (CSP) 和增强型扩展程序加载:如果您在加载扩展程序时遇到 CSP 违规问题,请检查管理 > 平台 > 扩展程序框架下的增强型扩展程序加载设置。
排查身份验证和 API 访问权限问题
扩展程序通过 Extension SDK 代表已登录的用户与 Looker API 进行交互。如果 API 调用失败,并在网络标签页中显示 401 Unauthorized 或 403 Forbidden 状态代码,请调查以下内容:
- 区分
401和403错误:401 Unauthorized:请求未通过身份验证。如果扩展程序 SDK 未正确初始化,或者扩展程序在 SDK 完成身份验证握手之前尝试进行 API 调用,通常会发生此错误。403 Forbidden:请求已通过身份验证,但登录用户缺少所需的 Looker 权限,或者扩展程序的manifest.lkml未在core_api_methods中包含调用的方法。
- 验证用户角色和权限:在管理 > 用户和管理 > 角色中,检查已登录用户分配的角色、权限集和模型集:
- 确认用户具有使用扩展程序的权限,包括对包含扩展程序的 LookML 模型和扩展程序查询的所有模型的模型集具有
access_data(以及explore或develop,视需要而定)权限。 - 确认用户的角色包含该扩展程序调用的每个 Looker API 端点所需的特定权限。
- 确认用户具有使用扩展程序的权限,包括对包含扩展程序的 LookML 模型和扩展程序查询的所有模型的模型集具有
- 确保在调用 API 之前 SDK 上下文已准备就绪:验证您的扩展程序代码是否会等待扩展程序 SDK 上下文初始化,然后再调用 API 方法。
排查扩展程序 SDK 和依赖项问题
npm 或 Yarn 软件包安装问题或缺少 SDK 提供方组件可能会导致扩展程序无法编译或连接到 Looker:
- 验证 Node.js 模块安装:在终端中,前往扩展程序项目的根目录,然后检查
node_modules目录:- 如果
node_modules缺失或依赖项似乎已损坏,请删除node_modules目录和锁定文件(yarn.lock或package-lock.json)。 - 可选:如果软件包安装反复失败,请清除软件包管理器缓存(例如,运行
npm cache clean --force)。 - 验证您安装的 Node.js 版本是否与项目的要求兼容,然后运行
yarn install或npm install以执行全新安装。
- 如果
- 检查
ExtensionProvider初始化:打开扩展程序的主入口文件(例如App.js或index.js),并确认<ExtensionProvider>(从@looker/extension-sdk-react导入)封装了需要 Looker SDK 上下文的应用组件:javascript ReactDOM.render( <ExtensionProvider> <App /> </ExtensionProvider>, document.getElementById('root') );如果缺少<ExtensionProvider>,或者您将其放置在调用 SDK 的组件之后,则子组件将无法访问 SDK 上下文。
排查运行时 JavaScript 和逻辑错误
如果扩展程序的配置、开发服务器、权限和 SDK 设置均有效,则问题可能是扩展程序的自定义 JavaScript 或 TypeScript 代码中存在运行时错误:
- 分析控制台堆栈轨迹:在浏览器的控制台标签页中,找到红色出错提示,然后点击展开箭头以查看完整的堆栈轨迹。堆栈轨迹的顶部行标识了源代码中发生错误的文件和行号。点击文件链接(例如
MyComponent.js:42),直接跳转到来源标签页中的相应行。 - 检查是否存在未定义或 null 值:对于
TypeError: Cannot read properties of undefined等错误,请在代码读取嵌套属性之前,验证异步 API 响应或属性是否已完成加载。添加防御性检查(例如if (myObject && myObject.property)或可选链myObject?.property)。 - 验证 API 响应格式:确认您的代码可以处理 Looker API 调用返回的实际数据结构(例如,在调用数组方法之前验证响应载荷是对象还是数组)。
- 使用断点和日志记录进行调试:在浏览器的来源标签页中,在失败行之前设置断点,以暂停执行并实时检查变量值,或添加
console.log()语句来跟踪执行流程。
验证 Looker 版本兼容性
Looker 中的主要功能更新或更改可能需要兼容版本的 Looker Extension SDK:
- 在扩展程序项目的
package.json文件中,检查@looker/extension-sdk(以及@looker/extension-sdk-react,如果使用)的版本。 - 在 Looker 网页界面中,在帮助 > 关于或管理 > 常规 > 设置下查看实例的当前发布版本。
- 将您的 Looker 发布版本与
@looker/extension-sdk文档中的兼容性说明进行比较。 - 如果您的 Looker 实例最近进行了升级,并且扩展程序使用的是过时的 SDK,或者扩展程序使用的是早期 Looker 版本不支持的较新 SDK 功能,请将 SDK 软件包更新到兼容的版本:
bash npm install @looker/extension-sdk@latest更新软件包后,请重新安装依赖项并重启开发服务器。
收集诊断信息
如果您在按照问题排查步骤操作后仍无法解决问题,请在与支持团队联系之前收集以下信息:
- Looker 实例和项目信息:
- Looker 实例网址(例如
instance_name.looker.com)。 - Looker 发布版本。
- 包含扩展程序的 LookML 项目的名称以及
manifest.lkml中的application名称。
- Looker 实例网址(例如
- 扩展程序配置和 SDK 详细信息:
manifest.lkml文件中application声明的副本或屏幕截图。package.json中指定的@looker/extension-sdk版本。- 扩展程序是在本地开发服务器 (
url) 上运行,还是已部署到生产环境 (file)。
- 错误日志和屏幕截图:
- 浏览器控制台和网络标签页中错误的屏幕截图或完整文本(包括失败的
4xx或5xx请求的请求标头和响应载荷)。 - 如果 API 调用持续返回
5xx服务器错误,请提供looker.log(对于客户托管的实例)或 Logging 中的 Logs Explorer(对于 Looker (Google Cloud Core) 实例)中匹配的日志摘录。
- 浏览器控制台和网络标签页中错误的屏幕截图或完整文本(包括失败的
- 问题排查摘要和重现步骤:
- 您已执行的问题排查步骤及其结果的摘要。
- 重现问题的确切步骤,或者如果您怀疑 Looker 扩展程序框架或扩展程序 SDK 存在问题,请提供一个可重现的最小示例。
与支持团队联系
如果您已验证上述所有步骤,但问题仍未解决,请执行以下操作: