|
@@ -1,6 +1,6 @@
|
|
|
import React from 'react';
|
|
|
import BN from 'bn.js';
|
|
|
-import axios, { CancelTokenSource } from 'axios';
|
|
|
+import axios, { CancelTokenSource, AxiosError, AxiosRequestConfig } from 'axios';
|
|
|
import { History } from 'history';
|
|
|
import { Progress, Message } from 'semantic-ui-react';
|
|
|
|
|
@@ -26,6 +26,7 @@ import { EditVideoView } from './upload/EditVideo.view';
|
|
|
|
|
|
import { IterableFile } from './IterableFile';
|
|
|
import { StorageProviderId } from '@joystream/types/working-group';
|
|
|
+import { normalizeError, isObjectWithProperties } from '@polkadot/joy-utils/functions/misc';
|
|
|
|
|
|
const MAX_FILE_SIZE_MB = 500;
|
|
|
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
|
|
@@ -41,7 +42,7 @@ type Props = ApiProps & I18nProps & DiscoveryProviderProps & MyAccountProps & {
|
|
|
};
|
|
|
|
|
|
type State = {
|
|
|
- error?: any;
|
|
|
+ error?: string;
|
|
|
file?: File;
|
|
|
computingHash: boolean;
|
|
|
ipfs_cid?: string;
|
|
@@ -91,7 +92,7 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
private renderContent () {
|
|
|
const { error, uploading, discovering, computingHash, sendingTx } = this.state;
|
|
|
|
|
|
- if (error) return this.renderError();
|
|
|
+ if (error) return this.renderError(error);
|
|
|
else if (discovering) return this.renderDiscovering();
|
|
|
else if (uploading) return this.renderUploading();
|
|
|
else if (computingHash) return this.renderComputingHash();
|
|
@@ -99,13 +100,11 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
else return this.renderFileInput();
|
|
|
}
|
|
|
|
|
|
- private renderError () {
|
|
|
- const { error } = this.state;
|
|
|
-
|
|
|
+ private renderError (error: string) {
|
|
|
return (
|
|
|
<Message error className='JoyMainStatus'>
|
|
|
<Message.Header>Failed to upload your file</Message.Header>
|
|
|
- <p>{error.toString()}</p>
|
|
|
+ <p>{error}</p>
|
|
|
<button className='ui button' onClick={this.resetForm}>Start over</button>
|
|
|
</Message>
|
|
|
);
|
|
@@ -223,7 +222,7 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
});
|
|
|
} else {
|
|
|
this.setState({ file, computingHash: true });
|
|
|
- this.startComputingHash();
|
|
|
+ void this.startComputingHash();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -236,7 +235,8 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
|
|
|
try {
|
|
|
const iterableFile = new IterableFile(file, { chunkSize: 65535 });
|
|
|
- const ipfs_cid = await IpfsHash.of(iterableFile);
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
|
|
+ const ipfs_cid = (await IpfsHash.of(iterableFile)) as string;
|
|
|
|
|
|
this.hashComputationComplete(ipfs_cid);
|
|
|
} catch (err) {
|
|
@@ -283,7 +283,7 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
dataObject = await api.query.dataDirectory.dataObjectByContentId(newContentId) as Option<DataObject>;
|
|
|
} catch (err) {
|
|
|
this.setState({
|
|
|
- error: err,
|
|
|
+ error: normalizeError(err),
|
|
|
discovering: false
|
|
|
});
|
|
|
|
|
@@ -299,10 +299,10 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
if (dataObject.isSome) {
|
|
|
const storageProvider = dataObject.unwrap().liaison;
|
|
|
|
|
|
- this.uploadFileTo(storageProvider);
|
|
|
+ void this.uploadFileTo(storageProvider);
|
|
|
} else {
|
|
|
this.setState({
|
|
|
- error: new Error('No Storage Provider assigned to process upload'),
|
|
|
+ error: 'No Storage Provider assigned to process upload',
|
|
|
discovering: false
|
|
|
});
|
|
|
}
|
|
@@ -313,7 +313,7 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
|
|
|
if (!file || !file.size) {
|
|
|
this.setState({
|
|
|
- error: new Error('No file to upload!'),
|
|
|
+ error: 'No file to upload!',
|
|
|
discovering: false
|
|
|
});
|
|
|
|
|
@@ -321,7 +321,7 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
}
|
|
|
|
|
|
const contentId = newContentId.encode();
|
|
|
- const config = {
|
|
|
+ const config: AxiosRequestConfig = {
|
|
|
headers: {
|
|
|
// TODO uncomment this once the issue fixed:
|
|
|
// https://github.com/Joystream/storage-node-joystream/issues/16
|
|
@@ -329,7 +329,15 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
'Content-Type': '' // <-- this is a temporary hack
|
|
|
},
|
|
|
cancelToken: cancelSource.token,
|
|
|
- onUploadProgress: (progressEvent: any) => {
|
|
|
+ onUploadProgress: (progressEvent: unknown) => {
|
|
|
+ if (
|
|
|
+ !isObjectWithProperties(progressEvent, 'loaded', 'total') ||
|
|
|
+ typeof progressEvent.loaded !== 'number' ||
|
|
|
+ typeof progressEvent.total !== 'number'
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
|
|
|
|
|
this.setState({
|
|
@@ -345,7 +353,7 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
url = await discoveryProvider.resolveAssetEndpoint(storageProvider, contentId, cancelSource.token);
|
|
|
} catch (err) {
|
|
|
return this.setState({
|
|
|
- error: new Error(`Failed to contact storage provider: ${err.message}`),
|
|
|
+ error: `Failed to contact storage provider: ${normalizeError(err)}`,
|
|
|
discovering: false
|
|
|
});
|
|
|
}
|
|
@@ -362,14 +370,20 @@ class Upload extends React.PureComponent<Props, State> {
|
|
|
|
|
|
try {
|
|
|
await axios.put<{ message: string }>(url, file, config);
|
|
|
- } catch (err) {
|
|
|
- this.setState({ progress: 0, error: err, uploading: false });
|
|
|
+ } catch (e) {
|
|
|
+ const err = e as unknown;
|
|
|
+
|
|
|
+ this.setState({ progress: 0, error: normalizeError(err), uploading: false });
|
|
|
|
|
|
if (axios.isCancel(err)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (!err.response || (err.response.status >= 500 && err.response.status <= 504)) {
|
|
|
+ const response = isObjectWithProperties(err, 'response')
|
|
|
+ ? (err as AxiosError).response
|
|
|
+ : undefined;
|
|
|
+
|
|
|
+ if (!response || (response.status >= 500 && response.status <= 504)) {
|
|
|
// network connection error
|
|
|
discoveryProvider.reportUnreachable(storageProvider);
|
|
|
}
|