一日一技:Bug分析,假删除导致文章发布成功却打不开的问题

简介: 一日一技:Bug分析,假删除导致文章发布成功却打不开的问题

公司有一个内部博客,大家可以在上面创建自己的账号,然后写文章在全公司分享。昨天这个内部博客开通了API,因此我准备写一个Python程序,把自己公众号文章都搬运上去。


然后我就发现这个API接口有一个bug。并且根据它的现象,猜到它问题出在哪里。

我先来简单描述一下现象。


假设我硬盘上现在有50个Markdown文件。现在我要把它发布到网站上。简化代码如下:


import glob
import requests
for path in glob.glob('blog/*.md'):
   with open(path) as f:
        article = f.read()
    requests.post('https://xxx.yyy.com/post?token=abcasdf', json={'content': content})


发布完成以后,文章确实都已经在网页上出现了,并且每篇文章都能正常显示。但我粗略浏览了一下,发现里面有一些文章的末尾带上来我的微信公众号二维码。我不想让公司的人知道我的公众号,所以准备修改一下文章。


有一些文章有二维码,有一些没有,一个一个改起来很麻烦,所以我做了两步操作。首先写了一个程序,扫描所有Markdown文件,发现二维码就删掉。然后,我直接在网站上把刚刚发布的所有文章都删了(懒得去看哪篇有二维码,哪篇没有,干脆全删了重发)。


接下来,我再次运行程序批量重新发布文章。2秒钟以后发布完成。


本来一切看起来都很正常,但是当我到网站上查看的时候,发现有很多文章点开以后,都提示『该文章已经删除』。


我一开始在想是不是我的程序写得不对,漏掉了这些文章。我重新单独一篇一篇发布这篇文章,API接口返回发布成功,可在网页上还是显示文章已经删除。


然后我一篇一篇检查这些发布失败的文章,发现有一个共同的特点:他们是一开始就没有二维码的文章。相当于这些文章我在网站上删除以后原样重新又发了一次。


那我就有了一个初步的猜测,大概知道原因是什么了:


  1. 因为每篇文章有一个docid,当第一次发布文章的时候,这个docid就是文章正文内容的md5值。只要文章完全一样,连续发多少次,它的docid都一样。这样就可以防止出现重复文章。(更新的时候,需要用户主动提供docid,避免重新生成新的)。


  1. 这个网站的删除功能,肯定是假删除。也就是当我点了删除文章的按钮时,文章其实依然在数据库里面,只不过增加了一个字段removed=True。网页显示文章的时候,查询条件肯定是col.find({'removed': {"$ne": True}}),所以就不会把这些被软删除的文章显示出来。


  1. API发布新文章的时候,肯定使用的是更新操作。并且使用了upsert=True


以MongoDB为例,这个API背后的逻辑肯定是这样的:


def post_article(docid, article_info):
      mongo.update_one({'_id': docid}, {'$set': article_info}, upsert=True)


upsert=True的作用,是先检查数据是否存在,如果存在就更新,如果不存在就插入。

第一次发布的时候,文章不存在,直接插入,正常。如果用户正常使用修改接口,修改了正文,因为用户主动提供了docid,所以也能正常更新。


但如果用户先删除了数据,此时数据库中,增加了一个字段removed=True。然后用户又原封不动重新发一次文章。那么docid肯定还是原来那个。这条文章已经在数据库中存在了。于是逐一更新了每个字段。但是新发布的字段里面是没有removed这个字段的,所以更新的时候不会更新它,它还在数据库里面。所以就出现了发布成功,但是打开新闻又提示文章已经删除。


我去问了一下做这个API的同学,果然它的bug原因跟我设想的一模一样。


这个bug解决方法非常简单,发布新文章的时候,把update_one改成replace_one就可以了:


def post_article(docid, article_info):
      mongo.replace_one({'_id': docid}, {'$set': article_info}, upsert=True)


请关注微信公众号【未闻Code】获取更多精彩文章。

目录
相关文章
|
3月前
bug长时间未修复该怎么办?
bug长时间未修复该怎么办?
bug长时间未修复该怎么办?
|
3月前
|
算法
搜索代码优化的常见错误BUG
搜索代码优化的常见错误BUG
|
3月前
|
算法 API 索引
写搜索代码一些常见错误BUG
写搜索代码一些常见错误BUG
|
6月前
|
小程序 Android开发 iOS开发
小程序 | 小程序修复了一些bug
前段时间,有朋友反应小程序的今天吃个啥有bug,不能正常使用。
|
8月前
|
安全 druid Java
【紧急】Apache Log4j任意代码执行漏洞安全风险升级修复教程
近期一个 Apache Log4j 远程代码执行漏洞细节被公开,攻击者利用漏洞可以远程执行代码。经过分析,该组件存在Java JNDI注入漏洞,当程序将用户输入的数据进行日志,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码。
209 1
|
监控 安全 架构师
抱歉,你测试的项目上线之后bug太多了!
抱歉,你测试的项目上线之后bug太多了!
|
Java 开发者
闯祸了,我用了一个‘<>’操作符引发的线上Bug
闯祸了,我用了一个‘<>’操作符引发的线上Bug
130 0
闯祸了,我用了一个‘<>’操作符引发的线上Bug
|
测试技术
软件测试面试题:软件缺陷(或者叫Bug)记录都包含了哪些内容?如何提交高质量的软件缺陷(Bug)记录?
软件测试面试题:软件缺陷(或者叫Bug)记录都包含了哪些内容?如何提交高质量的软件缺陷(Bug)记录?
274 0
|
安全 小程序 程序员
网站漏洞测试BUG寻找服务
很多网友以及站长朋友们对漏洞挖掘这个词很陌生,在讲漏洞挖掘之前,就是大家应该对漏洞挖掘可能不是很熟,这里就是其实顾名思义就是从这个名字来说,大家都可以知道什么叫漏洞挖掘,就是在网站上面大家应该有经常听过一些笑话,程序员去这种相亲网站相亲,然后我问他你今天找到了对象吗?程序员说没有,然后他说我今天找到了几个bug,像这种类似的bug或者是有危害性的,我们就叫漏洞,程序员在网站上寻找BUG的过程就是漏洞挖掘,这样比较通俗理解。
182 0
网站漏洞测试BUG寻找服务
|
SQL 前端开发 测试技术
特定场景下才能复现的bug案例分享之--前端排序字段的锅
在做功能测试的过程中,经常会遇到一些难以重现的bug,或者明明在自己电脑上是好的,但是在别人电脑上操作的时候就是会报错。