fix(downloads): Wait for download file stream to finalize before resolving and rendering inline attachments. Fixes T1210

Test Plan: No new tests, need to figure out how to prevent regression here.

Reviewers: evan

Reviewed By: evan

Maniphest Tasks: T1210

Differential Revision: https://phab.nylas.com/D1558
This commit is contained in:
Ben Gotow 2015-05-26 14:14:18 -07:00
parent 16979f371f
commit 480b0e799d
3 changed files with 37 additions and 6 deletions

View file

@ -112,11 +112,13 @@ class NylasAPI
return console.log('Cannot make Nylas request without auth token.') unless @APIToken
options.method ?= 'GET'
options.url ?= "#{@APIRoot}#{options.path}" if options.path
options.body ?= {} unless options.formData
options.json ?= true
options.auth = {'user': @APIToken, 'pass': '', sendImmediately: true}
options.error ?= @_defaultErrorCallback
unless options.method is 'GET' or options.formData
options.body ?= {}
request options, (error, response, body) =>
PriorityUICoordinator.settle.then =>
Actions.didMakeAPIRequest({request: options, response: response})

View file

@ -37,19 +37,49 @@ class Download
return reject(new Error("Must pass a fileID to download")) unless @fileId?
return reject(new Error("Must have a target path to download")) unless @targetPath?
# Does the file already exist on disk? If so, just resolve immediately.
fs.exists @targetPath, (exists) =>
# Does the file already exist on disk? If so, just resolve immediately.
return resolve(@) if exists
stream = fs.createWriteStream(@targetPath)
finished = false
finishedAction = null
# We need to watch the request for `success` or `error`, but not fire
# a callback until the stream has ended. These helper functions ensure
# that resolve or reject is only fired once regardless of the order
# these two events (stream end and `success`) happen in.
streamEnded = ->
finished = true
if finishedAction
finishedAction(@)
onStreamEnded = (action) ->
if finished
action(@)
else
finishedAction = action
@request = NylasAPI.makeRequest
json: false
path: "/n/#{namespace}/files/#{@fileId}/download"
success: => resolve(@)
error: => reject(@)
success: =>
# At this point, the file stream has not finished writing to disk.
# Don't resolve yet, or the browser will load only part of the image.
onStreamEnded(resolve)
error: =>
onStreamEnded(reject)
progress(@request, {throtte: 250})
.on("progress", (progress) =>
@percent = progress.percent
@progressCallback()
).pipe(fs.createWriteStream(@targetPath))
)
.on("end", =>
# Wait for the file stream to finish writing before we resolve or reject
stream.end(streamEnded)
)
.pipe(stream)
abort: ->
@request?.abort()

View file

@ -30,7 +30,6 @@ class FileUploadTask extends Task
path: "/n/#{@_namespaceId()}/files"
method: "POST"
json: false
returnsModel: true
formData: @_formData()
error: reject
success: (rawResponseString) =>