Skip to content

Commit

Permalink
[fix] handle undefined body on endpoint output (#1808)
Browse files Browse the repository at this point in the history
  • Loading branch information
ignatiusmb committed Jul 10, 2021
1 parent af1aa54 commit 34d2049
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-cheetahs-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

handle undefined body on endpoint output
15 changes: 7 additions & 8 deletions packages/kit/src/runtime/server/endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ export default async function render_route(request, route) {
const params = route.params(match);

const response = await handler({ ...request, params });
const preface = `Invalid response from route ${request.path}`;

if (response) {
if (typeof response !== 'object') {
return error(
`Invalid response from route ${request.path}: expected an object, got ${typeof response}`
);
return error(`${preface}: expected an object, got ${typeof response}`);
}

let { status = 200, body, headers = {} } = response;
Expand All @@ -41,25 +40,25 @@ export default async function render_route(request, route) {
// validation
if (type === 'application/octet-stream' && !(body instanceof Uint8Array)) {
return error(
`Invalid response from route ${request.path}: body must be an instance of Uint8Array if content type is application/octet-stream`
`${preface}: body must be an instance of Uint8Array if content type is application/octet-stream`
);
}

if (body instanceof Uint8Array && type !== 'application/octet-stream') {
return error(
`Invalid response from route ${request.path}: Uint8Array body must be accompanied by content-type: application/octet-stream header`
`${preface}: Uint8Array body must be accompanied by content-type: application/octet-stream header`
);
}

/** @type {import('types/hooks').StrictBody} */
let normalized_body;

if (
typeof body === 'object' &&
(!type || type === 'application/json' || type === 'application/json; charset=utf-8')
(typeof body === 'object' || typeof body === 'undefined') &&
(!type || type.startsWith('application/json'))
) {
headers = { ...headers, 'content-type': 'application/json; charset=utf-8' };
normalized_body = JSON.stringify(body);
normalized_body = JSON.stringify(body || {});
} else {
normalized_body = /** @type {import('types/hooks').StrictBody} */ (body);
}
Expand Down
39 changes: 39 additions & 0 deletions packages/kit/test/apps/basics/src/routes/endpoint-output/_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as assert from 'uvu/assert';

/** @type {import('test').TestMaker} */
export default function (test) {
test('not ok on void endpoint', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/empty', { method: 'DELETE' });
assert.equal(res.ok, false);
});
test('200 status on empty endpoint', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/empty');
assert.equal(res.status, 200);
assert.equal(await res.json(), {});
});

test('set-cookie without body', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/headers');
assert.equal(res.status, 200);
assert.equal(res.headers.has('set-cookie'), true);
});

test('200 status by default', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/body');
assert.equal(res.status, 200);
assert.equal(await res.text(), '{}');
});

test('does not throw on blob method', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/empty');
assert.type(await res.blob(), 'object');
});
test('does not throw on arrayBuffer method', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/empty');
assert.type(await res.arrayBuffer(), 'object');
});
test('does not throw on buffer method', null, async ({ fetch }) => {
const res = await fetch('/endpoint-output/empty');
assert.type(await res.buffer(), 'object');
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('@sveltejs/kit').RequestHandler} */
export function get() {
return { body: {} };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('@sveltejs/kit').RequestHandler} */
export function get() {
return {};
}

/** @type {import('@sveltejs/kit').RequestHandler} */
export function del() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('@sveltejs/kit').RequestHandler} */
export function get() {
return {
headers: {
'Set-Cookie': 'foo=bar'
}
};
}

0 comments on commit 34d2049

Please sign in to comment.