Search code examples
javascripthttpfrontendsveltesapper

How can i get right http status code on sapper?


I created register page, and submit without any input. I got 200 ok though backend server raise 400 reseponsed how can i get right status on my js code? web site screenshot

200 ok status code

backend error messages

below image is api call to my backend server and responsed 400 status

400 status

api.js

const base = 'https://gyma9z0wme.execute-api.ap-northeast-2.amazonaws.com/dev';
// const base = 'http://127.0.0.1:8000';

function send({ method, path, data, token }) {
    const fetch = process.browser ? window.fetch : require('node-fetch').default;

    const opts = { method, headers: {} };

    if (data) {
        opts.headers['Content-Type'] = 'application/json';
        opts.body = JSON.stringify(data);
    }

    if (token) {
        opts.headers['Authorization'] = `Bearer ${token}`;
    }

    return fetch(`${base}/${path}`, opts)
        .then(r => r.text())
        .then(json => {
            try {
                return JSON.parse(json);
            } catch (err) {
                return json;
            }
        });
}

export function get(path, token) {
    return send({ method: 'GET', path, token });
}

export function del(path, token) {
    return send({ method: 'DELETE', path, token });
}

export function post(path, data, token) {
    return send({ method: 'POST', path, data, token });
}

export function put(path, data, token) {
    return send({ method: 'PUT', path, data, token });
}

utils.js

export function post(endpoint, data) {
    return fetch(endpoint, {
        method: 'POST',
        credentials: 'include',
        body: JSON.stringify(data),
        headers: {
            'Content-Type': 'application/json'
        }
    }).then(r => r.json());
}

auth/register.js

import * as api from "api.js";

export function post(req, res) {
  const user = req.body;

  api.post("users", user).then(response => {
    if (response.user) {
      req.session.user = response;
    }

    res.setHeader("Content-Type", "application/json");

    res.end(JSON.stringify(response));
  });
}

register/index.svelte

<script>
  import { goto, stores } from "@sapper/app";
  import ListErrors from "../_components/ListErrors.svelte";
  import { post } from "utils.js";
  const { session } = stores();
  let username = "";
  let email = "";
  let password = "";
  let errors = null;
  async function submit(event) {
    const response = await post(`auth/register`, { username, email, password });
    // TODO handle network errors
    if (response.status === 400){
      errors = response;
    }
    if (response.sn) {
      $session.sn = response.sn;
      goto("/");
    }
  }
</script>

<svelte:head>
  <title>회원가입 • Razberry</title>
</svelte:head>

<div class="auth-page">
  <div class="container page">
    <div class="row">
      <div class="col-md-6 offset-md-3 col-xs-12">
        <h1 class="text-xs-center">회원가입</h1>
        <p class="text-xs-center">
          <a href="/login">이미 회원인가요?</a>
        </p>

        <ListErrors {errors} />

        <form on:submit|preventDefault={submit}>
          <fieldset class="form-group">
            <input
              class="form-control form-control-lg"
              type="text"
              placeholder="Your Name"
              bind:value={username} />
          </fieldset>
          <fieldset class="form-group">
            <input
              class="form-control form-control-lg"
              type="text"
              placeholder="Email"
              bind:value={email} />
          </fieldset>
          <fieldset class="form-group">
            <input
              class="form-control form-control-lg"
              type="password"
              placeholder="Password"
              bind:value={password} />
          </fieldset>
          <button class="btn btn-lg btn-primary pull-xs-right">회원가입</button>
        </form>
      </div>
    </div>
  </div>
</div>

I'm using realworld code.

https://github.com/sveltejs/realworld

Try logging in with incorrect information by here. you can get same result

https://realworld.svelte.dev/login


Solution

  • Might be that the server responds the request with a 200 / OK via http, even if there is an error on backend side. Bad behavior for a backend, but real world...

    On the other side you can add a .catch(()=>{}) statement to your fetch()ing function send in api.js to handle the error.

    The response status is not part of the error. The status can be found in response.status as you expected. So the server responds with a 200/OK HTTP Status.

    Take a look at the response body. I know a backend wich responds with 200/ok and in the body is a string "an error occured" :P