mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-28 12:37:00 +00:00
Merge pull request #2291 from transloadit/more-network-errors
Transloadit: Add NetworkError handling
This commit is contained in:
commit
dddb2a1f43
5 changed files with 64 additions and 44 deletions
|
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const AuthError = require('./AuthError')
|
||||
const NetworkError = require('@uppy/utils/lib/NetworkError')
|
||||
const fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError')
|
||||
|
||||
// Remove the trailing slash so we can always safely append /xyz.
|
||||
function stripSlash (url) {
|
||||
|
|
@ -134,18 +134,11 @@ module.exports = class RequestClient {
|
|||
get (path, skipPostResponse) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.preflightAndHeaders(path).then((headers) => {
|
||||
fetch(this._getUrl(path), {
|
||||
fetchWithNetworkError(this._getUrl(path), {
|
||||
method: 'get',
|
||||
headers: headers,
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.name === 'AbortError') {
|
||||
throw err
|
||||
} else {
|
||||
throw new NetworkError(err)
|
||||
}
|
||||
})
|
||||
.then(this._getPostResponseFunc(skipPostResponse))
|
||||
.then((res) => this._json(res).then(resolve))
|
||||
.catch((err) => {
|
||||
|
|
@ -159,19 +152,12 @@ module.exports = class RequestClient {
|
|||
post (path, data, skipPostResponse) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.preflightAndHeaders(path).then((headers) => {
|
||||
fetch(this._getUrl(path), {
|
||||
fetchWithNetworkError(this._getUrl(path), {
|
||||
method: 'post',
|
||||
headers: headers,
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.name === 'AbortError') {
|
||||
throw err
|
||||
} else {
|
||||
throw new NetworkError(err)
|
||||
}
|
||||
})
|
||||
.then(this._getPostResponseFunc(skipPostResponse))
|
||||
.then((res) => this._json(res).then(resolve))
|
||||
.catch((err) => {
|
||||
|
|
@ -185,19 +171,12 @@ module.exports = class RequestClient {
|
|||
delete (path, data, skipPostResponse) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.preflightAndHeaders(path).then((headers) => {
|
||||
fetch(`${this.hostname}/${path}`, {
|
||||
fetchWithNetworkError(`${this.hostname}/${path}`, {
|
||||
method: 'delete',
|
||||
headers: headers,
|
||||
credentials: 'same-origin',
|
||||
body: data ? JSON.stringify(data) : null
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.name === 'AbortError') {
|
||||
throw err
|
||||
} else {
|
||||
throw new NetworkError(err)
|
||||
}
|
||||
})
|
||||
.then(this._getPostResponseFunc(skipPostResponse))
|
||||
.then((res) => this._json(res).then(resolve))
|
||||
.catch((err) => {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ const io = requireSocketIo
|
|||
const Emitter = require('component-emitter')
|
||||
const has = require('@uppy/utils/lib/hasProperty')
|
||||
const parseUrl = require('./parseUrl')
|
||||
const NetworkError = require('@uppy/utils/lib/NetworkError')
|
||||
const fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError')
|
||||
|
||||
// Lazy load socket.io to avoid a console error
|
||||
// in IE 10 when the Transloadit plugin is not used.
|
||||
|
|
@ -78,6 +80,12 @@ class TransloaditAssembly extends Emitter {
|
|||
|
||||
this.emit('connect')
|
||||
})
|
||||
|
||||
socket.on('connect_failed', () => {
|
||||
this._onError(new NetworkError('Transloadit Socket.io connection error'))
|
||||
this.socket = null
|
||||
})
|
||||
|
||||
socket.on('error', () => {
|
||||
socket.disconnect()
|
||||
this.socket = null
|
||||
|
|
@ -143,7 +151,7 @@ class TransloaditAssembly extends Emitter {
|
|||
* 'status'.
|
||||
*/
|
||||
_fetchStatus ({ diff = true } = {}) {
|
||||
return fetch(this.status.assembly_ssl_url)
|
||||
return fetchWithNetworkError(this.status.assembly_ssl_url)
|
||||
.then((response) => response.json())
|
||||
.then((status) => {
|
||||
// Avoid updating if we closed during this request's lifetime.
|
||||
|
|
@ -156,6 +164,7 @@ class TransloaditAssembly extends Emitter {
|
|||
this.status = status
|
||||
}
|
||||
})
|
||||
.catch((err) => this._onError(err))
|
||||
}
|
||||
|
||||
update () {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
const fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError')
|
||||
|
||||
/**
|
||||
* A Barebones HTTP API client for Transloadit.
|
||||
*/
|
||||
|
|
@ -38,23 +40,25 @@ module.exports = class Client {
|
|||
data.append('num_expected_upload_files', expectedFiles)
|
||||
|
||||
const url = `${this.opts.service}/assemblies`
|
||||
return fetch(url, {
|
||||
return fetchWithNetworkError(url, {
|
||||
method: 'post',
|
||||
headers: this._headers,
|
||||
body: data
|
||||
}).then((response) => response.json()).then((assembly) => {
|
||||
if (assembly.error) {
|
||||
const error = new Error(assembly.error)
|
||||
error.details = assembly.message
|
||||
error.assembly = assembly
|
||||
if (assembly.assembly_id) {
|
||||
error.details += ' ' + `Assembly ID: ${assembly.assembly_id}`
|
||||
})
|
||||
.then((response) => response.json()).then((assembly) => {
|
||||
if (assembly.error) {
|
||||
const error = new Error(assembly.error)
|
||||
error.details = assembly.message
|
||||
error.assembly = assembly
|
||||
if (assembly.assembly_id) {
|
||||
error.details += ' ' + `Assembly ID: ${assembly.assembly_id}`
|
||||
}
|
||||
throw error
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
return assembly
|
||||
}).catch((err) => this._reportError(err, { url, type: 'API_ERROR' }))
|
||||
return assembly
|
||||
})
|
||||
.catch((err) => this._reportError(err, { url, type: 'API_ERROR' }))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +70,7 @@ module.exports = class Client {
|
|||
reserveFile (assembly, file) {
|
||||
const size = encodeURIComponent(file.size)
|
||||
const url = `${assembly.assembly_ssl_url}/reserve_file?size=${size}`
|
||||
return fetch(url, { method: 'post', headers: this._headers })
|
||||
return fetchWithNetworkError(url, { method: 'post', headers: this._headers })
|
||||
.then((response) => response.json())
|
||||
.catch((err) => this._reportError(err, { assembly, file, url, type: 'API_ERROR' }))
|
||||
}
|
||||
|
|
@ -88,7 +92,7 @@ module.exports = class Client {
|
|||
|
||||
const qs = `size=${size}&filename=${filename}&fieldname=${fieldname}&s3Url=${uploadUrl}`
|
||||
const url = `${assembly.assembly_ssl_url}/add_file?${qs}`
|
||||
return fetch(url, { method: 'post', headers: this._headers })
|
||||
return fetchWithNetworkError(url, { method: 'post', headers: this._headers })
|
||||
.then((response) => response.json())
|
||||
.catch((err) => this._reportError(err, { assembly, file, url, type: 'API_ERROR' }))
|
||||
}
|
||||
|
|
@ -100,7 +104,7 @@ module.exports = class Client {
|
|||
*/
|
||||
cancelAssembly (assembly) {
|
||||
const url = assembly.assembly_ssl_url
|
||||
return fetch(url, { method: 'delete', headers: this._headers })
|
||||
return fetchWithNetworkError(url, { method: 'delete', headers: this._headers })
|
||||
.then((response) => response.json())
|
||||
.catch((err) => this._reportError(err, { url, type: 'API_ERROR' }))
|
||||
}
|
||||
|
|
@ -111,7 +115,7 @@ module.exports = class Client {
|
|||
* @param {string} url The status endpoint of the assembly.
|
||||
*/
|
||||
getAssemblyStatus (url) {
|
||||
return fetch(url, { headers: this._headers })
|
||||
return fetchWithNetworkError(url, { headers: this._headers })
|
||||
.then((response) => response.json())
|
||||
.catch((err) => this._reportError(err, { url, type: 'STATUS_ERROR' }))
|
||||
}
|
||||
|
|
@ -121,7 +125,7 @@ module.exports = class Client {
|
|||
? `${err.message} (${err.details})`
|
||||
: err.message
|
||||
|
||||
return fetch('https://status.transloadit.com/client_error', {
|
||||
return fetchWithNetworkError('https://status.transloadit.com/client_error', {
|
||||
method: 'post',
|
||||
body: JSON.stringify({
|
||||
endpoint,
|
||||
|
|
@ -131,7 +135,8 @@ module.exports = class Client {
|
|||
client: this.opts.client,
|
||||
error: message
|
||||
})
|
||||
}).then((response) => response.json())
|
||||
})
|
||||
.then((response) => response.json())
|
||||
}
|
||||
|
||||
_reportError (err, params) {
|
||||
|
|
|
|||
15
packages/@uppy/utils/src/fetchWithNetworkError.js
Normal file
15
packages/@uppy/utils/src/fetchWithNetworkError.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
const NetworkError = require('@uppy/utils/lib/NetworkError')
|
||||
|
||||
/**
|
||||
* Wrapper around window.fetch that throws a NetworkError when appropriate
|
||||
*/
|
||||
module.exports = function fetchWithNetworkError (...options) {
|
||||
return fetch(...options)
|
||||
.catch((err) => {
|
||||
if (err.name === 'AbortError') {
|
||||
throw err
|
||||
} else {
|
||||
throw new NetworkError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -753,6 +753,18 @@ uppy.on('upload-error', (file, error, response) => {
|
|||
})
|
||||
```
|
||||
|
||||
If the error is related to network conditions — endpoint unreachable due to firewall or ISP blockage, for instance — the error will have `error.isNetworkError` property set to `true`. Here’s how you can check for network errors:
|
||||
|
||||
``` javascript
|
||||
uppy.on('upload-error', (file, error, response) => {
|
||||
if (error.isNetworkError) {
|
||||
// Let your users know that file upload could have failed
|
||||
// due to firewall or ISP issues
|
||||
alertUserAboutPossibleFirewallOrISPIssues(error)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### `upload-retry`
|
||||
|
||||
Fired when an upload has been retried (after an error, for example):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue