Fetch ошибка 400

I was wondering how we should handle 400 from backend when we use ajax function. We can make if statement in promise resolve function and check if res status is 400. Different approach is making wrapper service for fetch, and when we got 400 from server we throw exception. How to deal with that problem ?

VLAZ's user avatar

VLAZ

25.9k9 gold badges49 silver badges65 bronze badges

asked Oct 25, 2016 at 19:34

Artur Kasperek's user avatar

Artur KasperekArtur Kasperek

5452 gold badges5 silver badges17 bronze badges

5

I’d suggest a wrapper that checks response.ok which will be true if the response code is 2xx.

Note this statement from the MDN page on fetch():

An accurate check for a successful fetch() would include checking that
the promise resolved, then checking that the Response.ok property has
a value of true. An HTTP status of 404 does not constitute a network
error.

Here is a wrapper like this:

function fetchData() {
    return fetch.apply(null, arguments).then(response => {
         if (!response.ok) {
             // create error object and reject if not a 2xx response code
             let err = new Error("HTTP status code: " + response.status)
             err.response = response
             err.status = response.status
             throw err
         }
         return response
    })
}

leonheess's user avatar

leonheess

14.9k14 gold badges72 silver badges109 bronze badges

answered Oct 25, 2016 at 23:39

jfriend00's user avatar

jfriend00jfriend00

677k94 gold badges967 silver badges964 bronze badges

3

This way we can handle all types of status accordingly.

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify({ user_email: email }),
}).then((response) => {
  return new Promise((resolve) => response.json()
    .then((json) => resolve({
      status: response.status,
      ok: response.ok,
      json,
    })));
}).then(({ status, json, ok }) => {
  const message = json.message;
  let color = 'black';
  switch (status) {
    case 400:
      color = 'red';
      break;
    case 201:
    case 200:
      color = 'grey';
      break;
    case 500:
    default:
      handleUnexpected({ status, json, ok });
  }
})

inspiration

answered Feb 22, 2020 at 1:53

IsmailS's user avatar

Incorporating it into your HTTP abstraction is probably a good idea. Perhaps with some sort of options argument:

const myFetch = (method, path, {headers, strictErrors, whatever}) => {
  // fetch here, if strictErrors is true, reject on error.
  // return a Promise.
}

myFetch('GET', 'somepath', {strictErrors: true})
  .then(response => {})
  .catch(err => { /* maybe 400 */ });

A wrapper around fetch is generally a good idea, fetch is a relatively low level function. Just as it isn’t a good idea to directly create new XHR objects everywhere, I believe it isn’t a good idea to directly call fetch() in various parts of your application. It’s akin to a global variable, in some ways.

answered Oct 25, 2016 at 21:12

Madara's Ghost's user avatar

Madara’s GhostMadara’s Ghost

171k50 gold badges263 silver badges309 bronze badges

The best approach I’ve found for this is to wrap it in a new Promise, and if response.ok is false, reject the Promise with the error context.

/**
 * Parses the JSON returned by a network request
 *
 * @param  {object} response A response from a network request
 *
 * @return {object}          The parsed JSON, status from the response
 */
function parseJSON(response) {
  return new Promise((resolve) => response.json()
    .then((json) => resolve({
      status: response.status,
      ok: response.ok,
      json,
    })));
}

/**
 * Requests a URL, returning a promise
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [options] The options we want to pass to "fetch"
 *
 * @return {Promise}           The request promise
 */
export default function request(url, options) {
  return new Promise((resolve, reject) => {
    fetch(endpoint  + url, options)
      .then(parseJSON)
      .then((response) => {
        if (response.ok) {
          return resolve(response.json);
        }
        // extract the error from the server's json
        return reject(response.json.meta.error);
      })
      .catch((error) => reject({
        networkError: error.message,
      }));
  });
}

(Top comment on https://github.com/github/fetch/issues/203)

answered Dec 23, 2020 at 1:09

Jack Ryan's user avatar

Jack RyanJack Ryan

1,28712 silver badges26 bronze badges

I’m not that familiar with Javascript and spent way too much time with this but I ended up with a solution that was similar to, but not quite as beautiful as, the solution provided by @Siilwyn. I actually stumbled upon this page quite early in my research but didn’t know enough Javascript to recognize the solution staring in my face. So I’m going to take the time to explain it for future generations. ;-)

The way I see it any call to fetch will result in one of the following four outcomes:

  1. Network error
  2. Parsing error (Unreadable JSON from the server)
  3. Business logic error (Readable JSON error message from the server)
  4. Success

In order for our application to be robust it must be able to deal with all these outcomes. The original question stems from the problem that the response and json objects aren’t available in the same context. Use Promise.all() to fix that.

Network- and parsing errors causes exceptions and it would be nice to unify our error handling. Throw an Error when you get a business logic error message from the server. That way all types of errors end up in the catch-method.

Finally I’m guessing the original question stems from a desire to provide good error messages. Business logic error messages will be provided by the server but the network- and parsing error messages must be provided by us. In the example below I’ve created a map with the Exception type as the key and I’m using exception.constructor to do the lookup. Note that network- and parsing error messages are provided in place and that business logic error messages are grabbed from the exception which in turn was created using the message provided by the server.

fetch(URL, OPTS)
    .then(response => Promise.all([response, response.json()]))
    .then(([response, json]) => {
        if (!response.ok) {
            throw new Error(json.message);
        }

        render(json);
    })
    .catch(exception => {
        console.log(new Map([
            [TypeError, "There was a problem fetching the response."],
            [SyntaxError, "There was a problem parsing the response."],
            [Error, exception.message]]).get(exception.constructor));
    });


Go to learnjavascript


400 Bad Request — Failed to load resource; using fetch API

I’m trying to wrap my head around with what is going on between my fetch request and the REST API that the client consumes?

My REST API has been designed such that it is to accept a PUT request with a payload. If the API invalidates the request payload, it will return a 400 Bad Request along with a JSON response payload that contains a message informing the client why the request is bad. This happens if the user makes subsequent requests with the same payload. Here is an example of the client in fact receiving the payload for this scenario:

However, it appears that another error is raised Failed to load resource: the server responded with a status of 400 (Bad Request) :

Why would that error be raised when it is shown that the client in fact has the response payload? I’m figuring that it has to do with the client side than the server because the API performs as expected. Is it how I have my promises set up or is it something else?

Ultimately what I’m trying to do is send the response payload to the client in order to display the message as to what error has occurred.

vote_button.addEventListener("click", function(event) { voted_post = this.id.split("_") const _question = voted_post[0]; q_id = _question[_question.length - 1] vote = voted_post[1]
    const headers = new Headers({
      "Accept": "application/json",
      "Content-Type": "application/json",
      "X-CSRFToken": csrftoken
    });

    const request = new Request(
      `http://localhost:8000/api/v1/questions/${q_id}/`, {
        "method": "put",
        "headers": headers,
        "body": JSON.stringify({
          "vote": vote
        })
      }
    );

    function parseJson(response) {
      return new Promise((resolve, reject) => {
        return response.json()
      }).then((data) => {
        resolve({
          'data': data,
          'status_code': response.status,
          'ok': response.ok
        })
      })
    }
    fetch(request).then(parseJson).then((response) => {
      if (response.ok) {
        console.log(response)
      } else {
        throw new Error("request error message goes here")
      }
    }).catch((error) => console.log(error));

Добрый день.
Сделал запрос в postman и он успешен.
Там в заголовках нужно передать 3 параметра, логин, пароль и api key.

Работают оба, и get и post.

Но, когда пытаюсь получить данные через fetch, во vue, то получаю 400 bad reqeust.

created () {
      fetch("https://api.agimonline.com/v1/properties/list", {
          method: "POST",
          mode: "no-cors",
          headers: {
            "X-Api-User": "###",
            "X-Api-Pwd": "###",
            "X-Api-Key": "###"
          }
        }
      )
        .then(res => res.json())
        .then(data => console.log(data))
    }

Чего я не учел?

Заранее благодарен.

I face a problem with FE/BE integration. When I try to get back an offer object from PHP api I get a 400 error.

I use proxy get to API.

class OfferSite extends Component {
        state = {
                siteId: 1,
                offerId: 4,
                offerDetails: "",

        };

        componentDidMount = () => {

                const data = {
                        "siteId" : this.state.siteId,
                        "offerId" : this.state.offerId,
                };



                fetch('/v1/offers/details', {
                        method: "POST",
                        headers: {'Content-Type': 'application/json'},
                        body: JSON.stringify({"siteId" : 1, "offerId": 4}),
                })

                    .then((response) => response.json())
                    .then((data) => {
                            this.setState({offerDetails: data});
                            console.log(data);
                            })
        };

        render() {

                return (
                    <div>
                            <OfferCover />
                            <OfferMenu />
                            <OfferHighlights />
                            <OfferMovie />
                            <OfferResort />
                            <OfferAccomodation />
                            <OfferAttractions />
                            <OfferSchedule />
                            <OfferTransport />
                            <OfferCourses />
                            <OfferPrice />
                            <OfferAddons />
                            <OfferTrips />
                    </div>
                )


        }
}

export default OfferSite;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

And this is an error I get:

[object%20Module]:1 GET http://localhost:3000/[object%20Module] 400 (Bad Request)

I’ve spent about 6 hours already trying to find solution by myself and will appreciate any help :)

yudhiesh's user avatar

yudhiesh

6,2343 gold badges15 silver badges45 bronze badges

asked Dec 16, 2020 at 13:20

Koziol's user avatar

Problem:


Error 400 means that backend server can not process your request. In other words, your request does not follow the rules on backend server.

Solution:


At a glance, the API call syntax doesn’t seem to have a problem. First of all, check your request with Postman to make sure that the API endpoint works properly.

answered Dec 16, 2020 at 14:09

Thân LƯƠNG Đình's user avatar

Thân LƯƠNG ĐìnhThân LƯƠNG Đình

3,0422 gold badges11 silver badges21 bronze badges

1

Понравилась статья? Поделить с друзьями:
  • Fetch assoc php ошибка
  • Filezilla ошибка загрузки файла xml
  • Filezilla ошибка загрузки очереди
  • Filezilla ошибка gnu tls
  • Filezilla ошибка 530