-
Notifications
You must be signed in to change notification settings - Fork 155
Fix image not found response #179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
lib/storage-handler.js
Outdated
| reader.pipe(res); | ||
|
|
||
| reader.on('error', function onReaderError(err) { | ||
| res.set('content-type', 'application/json'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this error wasnt being caught before due to the test case, i believe this is also an issue on master (also returning the error in image/jpeg), but the test case doesnt cover it, even tho there are errors
Error: expected "Content-Type" matching /json/, got "image/jpeg; charset=utf-8"
at Test.assert (/Users/davidcheung/node-web/loopback-component-storage/node_modules/supertest/lib/test.js:196:25)
at assert (/Users/davidcheung/node-web/loopback-component-storage/node_modules/supertest/lib/test.js:132:12)
at /Users/davidcheung/node-web/loopback-component-storage/node_modules/supertest/lib/test.js:129:5
at Test.Request.callback (/Users/davidcheung/node-web/loopback-component-storage/node_modules/supertest/node_modules/superagent/lib/node/index.js:746:30)
at /Users/davidcheung/node-web/loopback-component-storage/node_modules/supertest/node_modules/superagent/lib/node/index.js:880:14
at IncomingMessage.<anonymous> (/Users/davidcheung/node-web/loopback-component-storage/node_modules/supertest/node_modules/superagent/lib/node/parsers/image.js:8:7)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:973:12)
at /Users/davidcheung/node-web/loopback-component-storage/node_modules/async-listener/glue.js:188:31
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback [as _tickCallback] (internal/process/next_tick.js:122:9)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps i should also pass res into processError() then set it there? @Amir-61
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps i should also pass res into processError() then set it there?
@davidcheung I'm not clear what you mean by passing res into processError()... could you please elaborate? AFAICT, processError(err, fileName) accepts err and fileName.
Also having the contect-type as application/json makes sense, in case of error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hard coding the content-type might be a bad idea because it might mean if your error handler returns a text/html 404, or anything else, the download()'s onError should not really make the assumption that the error must be in a form of application/json, and maybe we should perform content-negotiation with the request's accept to see what we set it as
where in our case processError() is the function that performs operation on the errorObject, so it might make sense to have such logic at the same place
my suggestion was to modify the signature of processError, but im not sure if that make sense either
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my suggestion was to modify the signature of processError, but im not sure if that make sense either
ummm that refactoring of processError() could make sense... @bajtos what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one thing I don't understand here. AFAIK, the error handler should be already setting the content-type header, taking into account content types acceptable by the client. Why do we need to set it again here, in the storage component?
I feel we may not understand the full picture and perhaps more investigation is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bajtos
it calls res.type https://github.com/strongloop/loopback-component-storage/blob/1.x/lib/storage-handler.js#L251 and never changes again, I believe because it is a download method, it does not perform a content-negotiation. but when has an error, it keeps such content-type
lb 2.x
then in rest-adapter strong-remoting@2.x it only does a res.send()
lb 3.x
in 3.x because the errorHandler defaults to sendJson(which also sets content-type) its not a problem https://github.com/strongloop/strong-error-handler/blob/f1d5f064f01fc3c00c15dc62cbde31a1767a77bd/lib/content-negotiation.js#L77-L85
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lb 2.x
then in rest-adapter strong-remoting@2.x it only does a res.send()
That looks like a bug in strong-remoting's default error handler. Can we fix strong-remoting instead of working around the problem here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in strongloop/strong-remoting#390
|
@slnode test please |
test/upload-download.test.js
Outdated
| .expect('Content-Type', /json/) | ||
| .expect(200, function(err, res) { | ||
| if (err) return done(err); | ||
| done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not replacing L351 and L352 with just:
done(err);
test/upload-download.test.js
Outdated
| .expect('Content-Type', /json/) | ||
| .expect(200, function(err, res) { | ||
| if (err) done(err); | ||
| done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bd46bb6 to
f475082
Compare
|
@slnode test please |
test/upload-download.test.js
Outdated
| .set('Content-Type', 'application/json') | ||
| .expect('Content-Type', /json/) | ||
| .expect(200, function(err, res) { | ||
| if (err) done(err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be the following?
if (err) return done(err);
Can you clarify what you are not returning here.
The same applies for other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a difference whether its returned?
the callback ends the test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a difference whether its returned?
the callback ends the test
You call the callback, but that does not mean it terminates the execution (unless you return the callback). In your case it also goes to the next line which is verifyMetadata(res.body, 'test-container');. @pthieu @bajtos to confirm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on the framework, test might stop at done(err) (but most of the time it's not); I'd say clear and objective code will be more easily debuggable in the future, so I'd suggest:
if (err) {
return done(err);
}
It's more clear, and no one can argue with you on behaviour
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, looked at other places in the code also returns the err
i guess it would avoid done() calling more than once
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't put the return, it doesn't short circuit at that line. You need it in this case to stop execution unless it's the last line in the func.
test/upload-download.test.js
Outdated
| .expect(200, function(err, res) { | ||
| if (err) done(err); | ||
| if (err) return done(err); | ||
| done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could have less code here; replacing L281-L282 with just:
done(err);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're not returning res, you could just:
.expect(200, done);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After fixing https://github.com/strongloop/loopback-component-storage/pull/179/files#r91399148 and squashing fixups, it LGTM.
test/upload-download.test.js
Outdated
| .expect(200, function(err, res) { | ||
| if (err) done(err); | ||
| if (err) return done(err); | ||
| done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're not returning res, you could just:
.expect(200, done);
test/upload-download.test.js
Outdated
| .expect('Content-Type', /json/) | ||
| .expect(200, function(err, res) { | ||
| done(); | ||
| done(err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (err)?
maybe just
.expect(200, done);
de76fdf to
2df5bc1
Compare
right now when download function is called and image is not found, it returns a JSON in
content-type: image/jpegwhich is suboptimal, this fixes it.jsonstrong-remoting#390)6/12/16:
Update 7/12/16
jsonstrong-remoting#390.