标签: bug

  • Bug求助+悬赏

    Bug求助+悬赏

    哎,老革命遇到新问题,创业+远程工作之后,想拉几个人跟我一起排查 bug 也找不到,只好公开求助+悬赏。

    首先请大家看下面这段视频:

    故障描述

    简单来说,我们做了一个网站:Dailylift.io。在这个网站上,你能描述自己今天的状态,然后得到一些心灵慰藉:你信仰的目标会给你写一封信。

    这个功能并不复杂,我选择用 Nuxt3 + Supabase 作为技术栈。我的理由是:

    1. 因为我们需要 SEO,我希望利用 Nuxt3 SSR 功能提升 SEO 效果。
    2. Supabase 提供包括开箱即用的用户系统在内的一系列 Serverless 功能,可以帮助我们的开发提速。
    3. Supabase 提供 Nuxt3 SDK,比 Auth0 更方便。
    4. Supabase 提供 VectorPG,方便我们使用 Embedding

    但是实际运行起来之后,却发现一些我未曾预料到的问题,主要跟用户登录状态有关。具体复现步骤为:

    1. 用户未登录时,先填写感受和目标,然后点“收信”,我们会要求他登录
    2. 用户登录后,我们需要先检查他的收信记录,确保每天只有收一封信
    3. 接下来,如果他今天还没有收信,我们就继续之前的过程,给他写信
    4. 但是偶尔,前面都正常,登录之后就卡住了,无法进入发信流程

    我尝试了很多方案,想解决这个问题,每次我都觉得自己搞定了,我甚至还写了一篇博客作为分享:使用 Vercel、Supabase、Stripe 打造 OpenAI 计费系统:2. 处理用户注册/登录。但是之后老板就会再次遇到这个问题,然后把我一通数落。我怎么也找不到稳定重现的方式,只能反复查验代码,希望找到其中的漏洞。

    我有几个怀疑:

    1. Nuxt + Supabase,理论上存在两个环境有用户态:SSR与浏览器。我不确定这里会不会有问题。比如,为了防止 refresh token 的时候触发 onAuthStateChange,我用 useSupabaseUser 获取初始用户状态。会不会是它导致后面判断出错了(很小概率)?
    2. 我需要先检查用户的邮件历史,再决定是否请求信件。这里可能也会有问题,比如两次请求之间的先后顺序。
    3. Supabase SSO 只支持 redirect,必须跳走再回来,所以浏览器里的状态无法保存。从第三方回来,处理 access_token 期间,可能因为网络状态、本地内存状态等,进入到某个我没处理的分支,导致失败。
    4. 登录之后,onAuthStateChange 到用户登录彻底完成之前,中间其实有一小段时间,会不会是网络问题导致它被卡住了?

    总之吧,我现在一个人开发,面对这些问题有些焦头烂额,所以希望所有看到这篇博客的同学,能帮我测试一下网站:Dailylift.io,帮我想想其中可能存在的坑,如果您有处理类似问题的经验,也请多分享一些。无论您:

    1. 帮我找到稳定重现的方式
    2. 帮我固定住 bug 出现的现场
    3. 帮我找到代码中潜藏的问题
    4. 引导我找到正确的方向
    5. 分享有价值的经验

    我一定大红包伺候!感谢大家,期待帮忙。


    更新:

    2023-08-31

    今天我早上测试的时候,遇到一个很诡异的问题:我通过 Google 登录后,遇到一个加载信件列表 400 错误,导致获取新信件失败。

    看路径和参数,这个请求应该是正常的。最诡异的是,我在 Devtools 里看不到这个错误,只能看到两个 GET /letters 的请求,都是正常 200。

    我现在怀疑这个问题是不是这样的:

    1. SSR 阶段它也会发起一个请求
    2. 这个请求在某个情况下会失败
    3. 这个失败会导致渲染出的页面携带着失败的状态,继而无法继续。

    另外,因为我们使用 TiDB Serverless,会不会是冷启动时会产生长延迟,导致 Vercel Serverless 失败?不过我看了数据库,也有很多是几个小时后成功的,也不太像。

  • webpack 入口是 vue 文件时,无法合并 CSS

    webpack 入口是 vue 文件时,无法合并 CSS

    在多页网站中合并 CSS 是很常见的优化手法。一般来说,CSS 体积不会太大,使用同一份 CSS,改进用户点击链接后的加载速度,大部分收益都大于多加载几 K CSS 带来的损耗。

    对于 UI 库来说也是如此,用统一的样式库,减少 import 时的心智负担,也是性价比很高的做法。

    最开始我在 UI 库的入口文件里 export 所有组件,然后在其它仓库里用 import {component} from 'my-components' 使用组件。后来通过分析得知,这样做无法 tree-shaking,而且会导致组件库的重复引用,即 A import B,B import C,那么无论 A 里有没有用到 C(比如用到 B 的一个小功能 b1,它不依赖 C),都会把 C 的代码打包进去。

    通过研读 Webpack 的 tree-shaking 文档,我得知也没有什么好办法可以规避这个问题,毕竟 JS 很灵活,你也不知道哪个开发者会搞个 eval('const myRequire = require'),如果要识别解析分辨所有情况太复杂,所以选择最保守的策略:认不出来具体功能的代码都给你带上。(早年我写 NerveNet 的时候,就是想不通这里怎么搞,最后坑掉了。早知道大家都选择绕开,说不定我的 NerveNet 也能如愿写出来了……)

    总之,目前 lodash 的做法比较常见且能解决问题,即增加多入口,为每个可能用到的函数都打包独立的函数。这样需要引用那个就引用哪个,不用担心把整个 lodash 都打包进去。

    于是我就立项开始重构我厂的几个前端库。然后很快就卡在 UI 库上面:无法生成合并过的 CSS 文件。Google 许久没有结果,吃饭前我灵机一动:vue-loader 必须搭配 VueLoaderPlugin 才能正确打包,会不会这个过程有 bug,导致如果我的入口都是 Vue 单文件组件,就会没法正确合并 CSS 文件。

    然后我就测试了一下,代码大约如下:

    // a.js
    import './a.styl'
    
    // b.js
    import './b.styl'

    可以生成合并过的 CSS 文件。与之相较,这样的 Vue 单文件组件就不行:

    // a.vue
    <style lang="stylus">
    body
      font-size 16px
    </style>
    
    // b.vue
    <style lang="stylus">
    body
      color red
    </style>

    但是,同样是 vue 单文件组件,样式使用 import 的方式导入,就没问题:

    // a.vue
    <script>
    import './a.styl';
    </script>
    
    // b.vue
    <script>
    import './b.styl';
    </script>

    现在可以确定是 vue-loader 或者 VueLoaderPlugin 有问题。不过最近身体欠佳,每天要花很多时间锻炼,另外还欠下不少坑要填,所以暂时没空去翻 issue 或者提 issue。哪位同学看见了,愿意帮忙的,可以搞一下,也算参与 开源社区建设了,功德无量。

  • 七牛 Node SDK 会导致 Electron 启动新实例

    七牛 Node SDK 会导致 Electron 启动新实例

    如题,暂时不确定是哪里导致的。

    总之,在 Electron 的 main process 里调用七牛云 SDK qiniu.io.putFile(),会启动一个新实例,原本的上传会暂停。这个时候关掉新实例,上传会继续。当前文件上传完成后,下个文件又会启动一个新实例。如此反复。

    文档中的代码如下:

    qiniu.io.putFile(uptoken, key, localFile, extra, function(err, ret) {
          if(!err) {
            // 上传成功, 处理返回值
            console.log(ret.hash, ret.key, ret.persistentId);       
          } else {
            // 上传失败, 处理返回代码
            console.log(err);
          }
    });
    

    已开 issue

    估计要等春节后修复了。

    暂时可以用社区版 SDK 先顶上。

  • Nexus S很诡异的单击变双击现象

    被报告了一个很诡异的Bug,在且只在三星Nexus S上出现,系统版本4.0.4和4.1.1都有:

    一次点击,会触发两次点击事件。两次事件的 target 和 currentTarget 都相同。

    因为只在三星Nexus S上出现,调试相当困难,反复无果。后来想起来我用zepto类库作为底层库,而且编译时把touch部分也编译进去了,所以尝试着将 click 替换为 tap ,居然解决了……

    具体问题症结,以后再研究吧。

  • 不推荐使用TortoiseGit 1.7.2版

    不推荐使用TortoiseGit 1.7.2版

    我很喜欢尝鲜,所以看到TortoiseGit升级到1.7.2版之后就兴冲冲跑去升了级,结果出现一个bug折腾到现在,终于还是放弃了。装回1.6.5之后一切正常。鉴于google到的资料(尤其是中文)非常有限,所以不建议大家安装最新版。

    PS:这会儿(2011-08-22 22:26)发现Google Code上1.7.2的下载链接已经去掉了,想必官方也发现了这个致命bug。

    PS2:官方已经发布了1.7.3版,修复了我所说的这个bug,可以试用。

    (更多…)