You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-12-19 10:22:30 +03:00
Merge pull request #229 from matrix-org/rav/fix_upload_error_parsing
Fix error handling on uploadContent
This commit is contained in:
@@ -495,6 +495,29 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
return this.opts.baseUrl + prefix + path + queryString;
|
return this.opts.baseUrl + prefix + path + queryString;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*
|
||||||
|
* @param {function} callback
|
||||||
|
* @param {string} method
|
||||||
|
* @param {string} uri
|
||||||
|
* @param {object} queryParams
|
||||||
|
* @param {object|string} data
|
||||||
|
* @param {object=} opts
|
||||||
|
*
|
||||||
|
* @param {boolean=true} opts.json Json-encode data before sending, and
|
||||||
|
* decode response on receipt. (We will still json-decode error
|
||||||
|
* responses, even if this is false.)
|
||||||
|
*
|
||||||
|
* @param {object=} opts.headers extra request headers
|
||||||
|
*
|
||||||
|
* @param {number=} opts.localTimeoutMs client-side timeout for the
|
||||||
|
* request. No timeout if undefined.
|
||||||
|
*
|
||||||
|
* @return {module:client.Promise} a promise which resolves to either the
|
||||||
|
* response object (if this.opts.onlyData is truthy), or the parsed
|
||||||
|
* body. Rejects
|
||||||
|
*/
|
||||||
_request: function(callback, method, uri, queryParams, data, opts) {
|
_request: function(callback, method, uri, queryParams, data, opts) {
|
||||||
if (callback !== undefined && !utils.isFunction(callback)) {
|
if (callback !== undefined && !utils.isFunction(callback)) {
|
||||||
throw Error(
|
throw Error(
|
||||||
@@ -510,6 +533,9 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
queryParams[key] = this.opts.extraParams[key];
|
queryParams[key] = this.opts.extraParams[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var json = opts.json === undefined ? true : opts.json;
|
||||||
|
|
||||||
var defer = q.defer();
|
var defer = q.defer();
|
||||||
|
|
||||||
var timeoutId;
|
var timeoutId;
|
||||||
@@ -540,7 +566,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
qs: queryParams,
|
qs: queryParams,
|
||||||
body: data,
|
body: data,
|
||||||
json: opts.json === undefined ? true : opts.json,
|
json: json,
|
||||||
timeout: localTimeoutMs,
|
timeout: localTimeoutMs,
|
||||||
headers: opts.headers || {},
|
headers: opts.headers || {},
|
||||||
_matrix_opts: this.opts
|
_matrix_opts: this.opts
|
||||||
@@ -552,7 +578,14 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
return; // already rejected promise
|
return; // already rejected promise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var handlerFn = requestCallback(defer, callback, self.opts.onlyData);
|
|
||||||
|
// if json is falsy, we won't parse any error response, so need
|
||||||
|
// to do so before turning it into a MatrixError
|
||||||
|
var parseErrorJson = !json;
|
||||||
|
var handlerFn = requestCallback(
|
||||||
|
defer, callback, self.opts.onlyData,
|
||||||
|
parseErrorJson
|
||||||
|
);
|
||||||
handlerFn(err, response, body);
|
handlerFn(err, response, body);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -579,14 +612,32 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
*
|
*
|
||||||
* If onlyData is true, the defer/callback is invoked with the body of the
|
* If onlyData is true, the defer/callback is invoked with the body of the
|
||||||
* response, otherwise the result code.
|
* response, otherwise the result code.
|
||||||
|
*
|
||||||
|
* If parseErrorJson is true, we will JSON.parse the body if we get a 4xx error.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
var requestCallback = function(defer, userDefinedCallback, onlyData) {
|
var requestCallback = function(
|
||||||
|
defer, userDefinedCallback, onlyData,
|
||||||
|
parseErrorJson
|
||||||
|
) {
|
||||||
userDefinedCallback = userDefinedCallback || function() {};
|
userDefinedCallback = userDefinedCallback || function() {};
|
||||||
|
|
||||||
return function(err, response, body) {
|
return function(err, response, body) {
|
||||||
if (!err && response.statusCode >= 400) {
|
if (!err) {
|
||||||
err = new module.exports.MatrixError(body);
|
try {
|
||||||
err.httpStatus = response.statusCode;
|
if (response.statusCode >= 400) {
|
||||||
|
if (parseErrorJson) {
|
||||||
|
// we won't have json-decoded the response.
|
||||||
|
body = JSON.parse(body);
|
||||||
|
}
|
||||||
|
err = new module.exports.MatrixError(body);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
err.httpStatus = response.statusCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -43,17 +43,13 @@ describe("MatrixClient", function() {
|
|||||||
httpBackend.when(
|
httpBackend.when(
|
||||||
"POST", "/_matrix/media/v1/upload"
|
"POST", "/_matrix/media/v1/upload"
|
||||||
).check(function(req) {
|
).check(function(req) {
|
||||||
console.log("Request", req);
|
|
||||||
|
|
||||||
expect(req.data).toEqual(buf);
|
expect(req.data).toEqual(buf);
|
||||||
expect(req.queryParams.filename).toEqual("hi.txt");
|
expect(req.queryParams.filename).toEqual("hi.txt");
|
||||||
expect(req.queryParams.access_token).toEqual(accessToken);
|
expect(req.queryParams.access_token).toEqual(accessToken);
|
||||||
expect(req.headers["Content-Type"]).toEqual("text/plain");
|
expect(req.headers["Content-Type"]).toEqual("text/plain");
|
||||||
expect(req.opts.json).toBeFalsy();
|
expect(req.opts.json).toBeFalsy();
|
||||||
expect(req.opts.timeout).toBe(undefined);
|
expect(req.opts.timeout).toBe(undefined);
|
||||||
}).respond(200, {
|
}).respond(200, "content");
|
||||||
"content_uri": "uri"
|
|
||||||
});
|
|
||||||
|
|
||||||
var prom = client.uploadContent({
|
var prom = client.uploadContent({
|
||||||
stream: buf,
|
stream: buf,
|
||||||
@@ -69,8 +65,8 @@ describe("MatrixClient", function() {
|
|||||||
expect(uploads[0].loaded).toEqual(0);
|
expect(uploads[0].loaded).toEqual(0);
|
||||||
|
|
||||||
prom.then(function(response) {
|
prom.then(function(response) {
|
||||||
console.log("Response", response);
|
// for backwards compatibility, we return the raw JSON
|
||||||
expect(response.content_uri).toEqual("uri");
|
expect(response).toEqual("content");
|
||||||
|
|
||||||
var uploads = client.getCurrentUploads();
|
var uploads = client.getCurrentUploads();
|
||||||
expect(uploads.length).toEqual(0);
|
expect(uploads.length).toEqual(0);
|
||||||
@@ -79,6 +75,33 @@ describe("MatrixClient", function() {
|
|||||||
httpBackend.flush();
|
httpBackend.flush();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should parse errors into a MatrixError", function(done) {
|
||||||
|
// opts.json is false, so request returns unparsed json.
|
||||||
|
httpBackend.when(
|
||||||
|
"POST", "/_matrix/media/v1/upload"
|
||||||
|
).check(function(req) {
|
||||||
|
expect(req.data).toEqual(buf);
|
||||||
|
expect(req.opts.json).toBeFalsy();
|
||||||
|
}).respond(400, JSON.stringify({
|
||||||
|
"errcode": "M_SNAFU",
|
||||||
|
"error": "broken",
|
||||||
|
}));
|
||||||
|
|
||||||
|
client.uploadContent({
|
||||||
|
stream: buf,
|
||||||
|
name: "hi.txt",
|
||||||
|
type: "text/plain",
|
||||||
|
}).then(function(response) {
|
||||||
|
throw Error("request not failed");
|
||||||
|
}, function(error) {
|
||||||
|
expect(error.httpStatus).toEqual(400);
|
||||||
|
expect(error.errcode).toEqual("M_SNAFU");
|
||||||
|
expect(error.message).toEqual("broken");
|
||||||
|
}).catch(utils.failTest).done(done);
|
||||||
|
|
||||||
|
httpBackend.flush();
|
||||||
|
});
|
||||||
|
|
||||||
it("should return a promise which can be cancelled", function(done) {
|
it("should return a promise which can be cancelled", function(done) {
|
||||||
var prom = client.uploadContent({
|
var prom = client.uploadContent({
|
||||||
stream: buf,
|
stream: buf,
|
||||||
|
|||||||
Reference in New Issue
Block a user