聊天上传错误

您好,我想报告一个在上传文件或图片到聊天私信时发现的问题。

  • 用户 A 在帖子或聊天中上传文件 A 时,一切正常,文件会正确注册。

  • 但是,当用户 B 下载文件 A 然后尝试在另一个聊天中重新上传它时:

    • 如果用户 B 不带文字发送文件,他们会收到一个错误:

      Message is too short, must have a minimum of 1 character.
      
      
    • 如果用户 B 带文字发送文件,则只有文字被发送——附件丢失。

然而,如果用户 A 重新上传同一个文件,它会正常工作,并且文件会包含在消息中。

我的问题是:
这是预期的行为吗,即只有原始上传者才能重新使用已上传的文件?还是其他用户也应该能够上传和发送同一个文件到聊天中?

1 个赞

这听起来有点像个小故障,有人会在未来几周内查看一下,我很乐意在此期间为它添加一个“欢迎PR”的标签。

1 个赞

我花了一些时间才弄清楚这一点,但我想我找到了原因。我认为这与此代码有关:

def fetch_uploads(params:, guardian:)
  return [] if !SiteSetting.chat_allow_uploads
  guardian.user.uploads.where(id: params.upload_ids) # 特别是这里
end

当创建一个新的聊天消息时,会调用此方法来获取要附加到消息的上传文件。可能是为了确保所有权,该方法会通过 Guardian 的用户来获取上传文件,以便只允许属于该用户的上传文件。

问题在于上传文件是重复的,正如此处所示:

# 我们已经有那个上传文件了吗?
@upload = Upload.find_by(sha1: sha1)

# ...

# 如果有,则返回之前的上传文件
if @upload
  add_metadata!
  UserUpload.find_or_create_by!(user_id: user_id, upload_id: @upload.id) if user_id
  return @upload
end

认为一个可能的修复方法是遍历 UserUpload 而不是仅仅考虑属于用户的上传文件。UserUpload 将上传文件链接到多个用户,这似乎是我们需要的。我还不能 100% 确定如何正确地做到这一点;时间不早了,我要去睡了,但如果其他人没有修复它,我稍后会回来尝试做一个 PR。:slightly_smiling_face:

3 个赞

这是一个绝妙的发现,而且非常准确。 :hugs:

上传文件有一个 user_id,但这只是创建上传文件的原始用户。

将该代码转换为:

Upload.where(id: params.upload_ids).joins(:user_uploads).where(user_uploads: { user_id: guardian.user.id })

就能解决问题。

你能提交一个 PR 吗!

谢谢,我不确定如何最好地构建该查询(我在这里相当新 :slightly_smiling_face:)。我将着手进行 PR。

3 个赞

好的,我终于完成了PR。抱歉耽搁了,生活中的一些事情耽误了。

修复:在聊天消息中,按 UserUpload 过滤上传,而不是按 Upload.user by clechasseur · Pull Request #34596 · discourse/discourse

我看到一些测试失败了,但这些并不是我修改过的测试。我在本地运行这些文件中的测试时也遇到了问题——我看到了和这里一样的重复键错误……我不确定是我弄坏了什么,还是测试有时不稳定……

一个好的经验法则是至少重新运行三次失败的测试,只有在第三次仍然失败时才开始恐慌😜

话虽如此,@j.jaffeux 也许能帮忙?

1 个赞

是的,这些只是不稳定的和其他随机错误,你的更改没问题。重新运行 PR 测试,如果通过或只是以相同的随机序列错误失败,我将批准并合并。

1 个赞

我太喜欢恐怖片了,不知道重复三次会发生什么 :sweat_smile:

2 个赞

此 PR 已合并,再次感谢 @clechasseur 的贡献 :rocket:

6 个赞