Parcourir la source

core: enrich error event for use from postproocessor (#2909)

Fixes: https://github.com/transloadit/uppy/issues/2840
Antoine du Hamel il y a 3 ans
Parent
commit
1aa17533ee

+ 19 - 23
packages/@uppy/core/src/index.js

@@ -1074,35 +1074,31 @@ class Uppy {
    * `error`, `file-removed`, `upload-progress`
    */
   _addListeners () {
-    this.on('error', (error) => {
-      let errorMsg = 'Unknown error'
-      if (error.message) {
-        errorMsg = error.message
-      }
-
+    /**
+     * @param {Error} error
+     * @param {object} [file]
+     * @param {object} [response]
+     */
+    const errorHandler = (error, file, response) => {
+      let errorMsg = error.message || 'Unknown error'
       if (error.details) {
         errorMsg += ` ${error.details}`
       }
 
       this.setState({ error: errorMsg })
-    })
 
-    this.on('upload-error', (file, error, response) => {
-      let errorMsg = 'Unknown error'
-      if (error.message) {
-        errorMsg = error.message
-      }
-
-      if (error.details) {
-        errorMsg += ` ${error.details}`
+      if (file != null) {
+        this.setFileState(file.id, {
+          error: errorMsg,
+          response,
+        })
       }
+    }
 
-      this.setFileState(file.id, {
-        error: errorMsg,
-        response,
-      })
+    this.on('error', errorHandler)
 
-      this.setState({ error: error.message })
+    this.on('upload-error', (file, error, response) => {
+      errorHandler(error, file, response)
 
       if (typeof error === 'object' && error.message) {
         const newError = new Error(error.message)
@@ -1514,7 +1510,7 @@ class Uppy {
       this.log(`Not setting result for an upload that has been removed: ${uploadID}`)
       return
     }
-    const currentUploads = this.getState().currentUploads
+    const { currentUploads } = this.getState()
     const currentUpload = { ...currentUploads[uploadID], result: { ...currentUploads[uploadID].result, ...data } }
     this.setState({
       currentUploads: { ...currentUploads, [uploadID]: currentUpload },
@@ -1629,7 +1625,7 @@ class Uppy {
         return
       }
       const currentUpload = currentUploads[uploadID]
-      const result = currentUpload.result
+      const { result } = currentUpload
       this.emit('complete', result)
 
       this._removeUpload(uploadID)
@@ -1653,7 +1649,7 @@ class Uppy {
       this.log('No uploader type plugins are used', 'warning')
     }
 
-    let files = this.getState().files
+    let { files } = this.getState()
 
     const onBeforeUploadResult = this.opts.onBeforeUpload(files)
 

+ 23 - 0
packages/@uppy/core/src/index.test.js

@@ -558,6 +558,29 @@ describe('src/Core', () => {
         uploadStarted: null,
       })
     })
+
+    it('should report an error if post-processing a file fails', () => {
+      const core = new Core()
+
+      core.addFile({
+        source: 'jest',
+        name: 'foo.jpg',
+        type: 'image/jpeg',
+        data: new File([sampleImage], { type: 'image/jpeg' }),
+      })
+
+      const fileId = Object.keys(core.getState().files)[0]
+      const file = core.getFile(fileId)
+      core.emit('error', new Error('foooooo'), file)
+
+      expect(core.getState().error).toEqual('foooooo')
+
+      expect(core.upload()).resolves.toMatchObject({
+        failed: [
+          { name: 'foo.jpg' },
+        ],
+      })
+    })
   })
 
   describe('uploaders', () => {

+ 4 - 0
website/src/docs/writing-plugins.md

@@ -152,6 +152,10 @@ When `mode` is `'determinate'`, also add the `value` property:
 
  - `value` - A progress value between 0 and 1.
 
+ ### `error(err\[, fileID\])
+
+ `err` is an `Error` object. `fileID` can optionally which file fails to inform the user.
+
 ## UI Plugins
 
 UI Plugins can be used to show a user interface. Uppy plugins use [preact](https://preactjs.com) v8.2.9 for rendering. preact is a very small React-like library that works really well with Uppy's state architecture. Uppy implements preact rendering in the `mount(target)` and `update()` plugin methods, so if you want to write a custom UI plugin using some other library, you can override those methods.