file-upload - GraphQL 文件上传的拒绝和错误处理

标签 file-upload error-handling upload graphql express-graphql

我有一个带有接受单个文件的解析器的快速 GraphQL 端点。解析器包括对接收到的文件的简单验证。

问题是当验证失败时,没有办法立即将错误返回给前端,因为抛出错误并不会强制中断上传请求。

一个过度简化的例子:

fileUpload: async (parent, { file, otherdata }) => {
    const isValid = (some logic here)
    if(!isValid)
        throw new ApolloError('upload parameters not valid')

    //No need to get this far,
    //we could have rejected the request already by examining otherdata,
    //or the stream could be already created for max time utilization

    const { createReadStream, filename, mimetype, encoding } = await file;
    const readStream = await createReadStream()
    ...
 }

预期行为:解析器返回通常的 {errors:[], data:null} 对象 - 或错误本身 - 取决于错误策略选项。

实际行为:错误在后端抛出,但请求在前端保持挂起状态。

我已经尝试过以下方法但没有成功:

  • 无论如何都要初始化 readStream 并在其上调用 .destroy()。结果是读取流停止,请求永远挂起。
  • 在解析器上下文中包含请求对象(也尝试了响应对象)并在其上调用 .destroy()。这会结束请求,但会导致前端出现网络错误,无法进行特定错误处理。

一些说明:

  • 显然也有客户端验证,但这并没有使服务器端验证变得不必要。
  • 等待上传完成然后抛出错误显然可行,但从时间和带宽角度来看,这并不是一个真正的选择。

我知道使用 GraphQL 上传文件是边缘支持的功能,但在这种情况下,我们讨论的是一个相当基本的操作。

如果有任何建议,我将不胜感激!

最佳答案

事实证明,这是默认的快速行为,与 GraphQL 接口(interface)完全无关。 解决方案的纯 express 版本可以找到here .

请求和响应对象应该传递给解析器上下文:

const apollo = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req, res }) => {
        return {
            req,
            res
        };
    }
});

然后在解析器中,根据例子:

fileUpload: async (parent, { file, otherdata }, {req, res}) => {
    const isValid = (some logic here)
    if(!isValid){
        res.send(403).send("Some message")
        // Throwing ApolloError could also work,
        // in which case response object would not be required, but not tested.
        // throw new ApolloError('upload parameters not valid')
        return req.destroy()
    }
        

    //No need to get this far,
    //we could have rejected the request already by examining otherdata,
    //or the stream could be already created for max time utilization

    const { createReadStream, filename, mimetype, encoding } = await file;
    const readStream = await createReadStream()
    ...
 }

关于file-upload - GraphQL 文件上传的拒绝和错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59355574/

相关文章:

file-upload - 使用 Content-Type multipart/form-data POST 数据

java - Apache CXF 拦截器覆盖内容类型

c# - 如何上传 pdf 文件?

c++ - "' x' 的问题未在此范围内声明”

python - 使用 pycurl 进行 FTP 上传的进度函数调用过于频繁

php - 奇怪的 CodeIgniter 上传问题

file-upload - 如何从 node.js 上传文件

C# 赋予控件数组属性

python - 我的 PuLP (使用线性编程的批量大小)代码中不断出现错误,出了什么问题?

Laravel 数据上传进度条