added size and duration to connection error reporting

This commit is contained in:
Danny Coates 2019-08-08 09:52:22 -07:00
parent 0729064753
commit 96c750c098
No known key found for this signature in database
GPG Key ID: 4C442633C62E00CB
5 changed files with 28 additions and 19 deletions

View File

@ -11,6 +11,15 @@ if (!fileProtocolWssUrl) {
fileProtocolWssUrl = 'wss://send.firefox.com/api/ws'; fileProtocolWssUrl = 'wss://send.firefox.com/api/ws';
} }
export class ConnectionError extends Error {
constructor(cancelled, duration, size) {
super(cancelled ? '0' : 'connection closed');
this.cancelled = cancelled;
this.duration = duration;
this.size = size;
}
}
export function setFileProtocolWssUrl(url) { export function setFileProtocolWssUrl(url) {
localStorage && localStorage.setItem('wssURL', url); localStorage && localStorage.setItem('wssURL', url);
fileProtocolWssUrl = url; fileProtocolWssUrl = url;
@ -150,10 +159,7 @@ function listenForResponse(ws, canceller) {
function handleClose(event) { function handleClose(event) {
// a 'close' event before a 'message' event means the request failed // a 'close' event before a 'message' event means the request failed
ws.removeEventListener('message', handleMessage); ws.removeEventListener('message', handleMessage);
const error = canceller.cancelled reject(new ConnectionError(canceller.cancelled));
? canceller.error
: new Error('connection closed');
reject(error);
} }
function handleMessage(msg) { function handleMessage(msg) {
ws.removeEventListener('close', handleClose); ws.removeEventListener('close', handleClose);
@ -183,6 +189,8 @@ async function upload(
onprogress, onprogress,
canceller canceller
) { ) {
let size = 0;
const start = Date.now();
const host = window.location.hostname; const host = window.location.hostname;
const port = window.location.port; const port = window.location.port;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
@ -210,7 +218,6 @@ async function upload(
const reader = stream.getReader(); const reader = stream.getReader();
let state = await reader.read(); let state = await reader.read();
let size = 0;
while (!state.done) { while (!state.done) {
if (canceller.cancelled) { if (canceller.cancelled) {
ws.close(); ws.close();
@ -236,7 +243,12 @@ async function upload(
} }
await completedResponse; await completedResponse;
uploadInfo.duration = Date.now() - start;
return uploadInfo; return uploadInfo;
} catch (e) {
e.size = size;
e.duration = Date.now() - start;
throw e;
} finally { } finally {
if (![WebSocket.CLOSED, WebSocket.CLOSING].includes(ws.readyState)) { if (![WebSocket.CLOSED, WebSocket.CLOSING].includes(ws.readyState)) {
ws.close(); ws.close();
@ -257,7 +269,6 @@ export function uploadWs(
return { return {
cancel: function() { cancel: function() {
canceller.error = new Error(0);
canceller.cancelled = true; canceller.cancelled = true;
}, },
@ -297,7 +308,7 @@ async function downloadS(id, keychain, signal) {
return response.body; return response.body;
} }
async function tryDownloadStream(id, keychain, signal, tries = 1) { async function tryDownloadStream(id, keychain, signal, tries = 2) {
try { try {
const result = await downloadS(id, keychain, signal); const result = await downloadS(id, keychain, signal);
return result; return result;
@ -319,7 +330,7 @@ export function downloadStream(id, keychain) {
} }
return { return {
cancel, cancel,
result: tryDownloadStream(id, keychain, controller.signal, 2) result: tryDownloadStream(id, keychain, controller.signal)
}; };
} }
@ -359,7 +370,7 @@ async function download(id, keychain, onprogress, canceller) {
}); });
} }
async function tryDownload(id, keychain, onprogress, canceller, tries = 1) { async function tryDownload(id, keychain, onprogress, canceller, tries = 2) {
try { try {
const result = await download(id, keychain, onprogress, canceller); const result = await download(id, keychain, onprogress, canceller);
return result; return result;
@ -380,7 +391,7 @@ export function downloadFile(id, keychain, onprogress) {
} }
return { return {
cancel, cancel,
result: tryDownload(id, keychain, onprogress, canceller, 2) result: tryDownload(id, keychain, onprogress, canceller)
}; };
} }

View File

@ -176,14 +176,13 @@ export default function(state, emitter) {
} catch (err) { } catch (err) {
if (err.message === '0') { if (err.message === '0') {
//cancelled. do nothing //cancelled. do nothing
const duration = Date.now() - start; metrics.cancelledUpload(archive, err.duration);
metrics.cancelledUpload(archive, duration);
render(); render();
} else { } else {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error(err); console.error(err);
state.raven.captureException(err); state.raven.captureException(err);
metrics.stoppedUpload(archive); metrics.stoppedUpload(archive, err.duration);
emitter.emit('pushState', '/error'); emitter.emit('pushState', '/error');
} }
} finally { } finally {

View File

@ -153,7 +153,7 @@ export default class FileReceiver extends Nanobus {
const downloadPath = `/api/download/${this.fileInfo.id}`; const downloadPath = `/api/download/${this.fileInfo.id}`;
let downloadUrl = getApiUrl(downloadPath); let downloadUrl = getApiUrl(downloadPath);
if (downloadUrl === downloadPath) { if (downloadUrl === downloadPath) {
downloadUrl = `${location.protocol}//${location.host}/api/download/${this.fileInfo.id}`; downloadUrl = `${location.protocol}//${location.host}${downloadPath}`;
} }
const a = document.createElement('a'); const a = document.createElement('a');
a.href = downloadUrl; a.href = downloadUrl;

View File

@ -44,7 +44,6 @@ export default class FileSender extends Nanobus {
} }
async upload(archive, bearerToken) { async upload(archive, bearerToken) {
const start = Date.now();
if (this.cancelled) { if (this.cancelled) {
throw new Error(0); throw new Error(0);
} }
@ -76,7 +75,6 @@ export default class FileSender extends Nanobus {
this.emit('progress'); // HACK to kick MS Edge this.emit('progress'); // HACK to kick MS Edge
try { try {
const result = await this.uploadRequest.result; const result = await this.uploadRequest.result;
const time = Date.now() - start;
this.msg = 'notifyUploadEncryptDone'; this.msg = 'notifyUploadEncryptDone';
this.uploadRequest = null; this.uploadRequest = null;
this.progress = [1, 1]; this.progress = [1, 1];
@ -87,8 +85,8 @@ export default class FileSender extends Nanobus {
name: archive.name, name: archive.name,
size: archive.size, size: archive.size,
manifest: archive.manifest, manifest: archive.manifest,
time: time, time: result.duration,
speed: archive.size / (time / 1000), speed: archive.size / (result.duration / 1000),
createdAt: Date.now(), createdAt: Date.now(),
expiresAt: Date.now() + archive.timeLimit * 1000, expiresAt: Date.now() + archive.timeLimit * 1000,
secretKey: secretKey, secretKey: secretKey,

View File

@ -107,9 +107,10 @@ function completedUpload(archive, duration) {
}); });
} }
function stoppedUpload(archive) { function stoppedUpload(archive, duration = 0) {
return addEvent('client_upload', { return addEvent('client_upload', {
download_limit: archive.dlimit, download_limit: archive.dlimit,
duration: sizeOrder(duration),
file_count: archive.numFiles, file_count: archive.numFiles,
password_protected: !!archive.password, password_protected: !!archive.password,
size: sizeOrder(archive.size), size: sizeOrder(archive.size),