Go-ipfs: Return a 404 instead of a 500 http code when dnslink not found for domain

Created on 4 Nov 2019  路  9Comments  路  Source: ipfs/go-ipfs

The gateways get a lot of dns api http requests for things like

https://ipfs.io/api/v0/dns/www.google.com?r=true

The api returns valid json and a 500 http code. It makes it hard to spot actual errors or other 500 repsonses from go-ipfs in the logs. A 404 would more closely match the situation that you asked for a dnslink resolution for a domain that does not have one.

kinenhancement topigateway topihttp-api

All 9 comments

@lidel what say you?

This is part of a bigger problem: 500 is returned instead of 4xx all over the API _and Gateway_.

In this specific case it should be fairly safe to change response code: dnslink lookup result status code is usually compared against 200, so it does not matter if negative result is 500, 300 or even >200

Personal nit: I don't like 404 Not Found because it is vague: could mean "no dnslink" OR "someone misconfigured nginx and API endpoint does not exist". 204 No Content would be a better response here imo :ok_hand:

Agree with @lidel regarding the 204 status code.

The HTTP API is an RPC API over HTTP, not a REST API. Trying to make it conform to REST semantics was _much_ more trouble than it was worth.

HTTP Codes are used at the _RPC_ layer:

  • 500 - RPC endpoint returned an error.
  • 404 - RPC endpoint doesn't exist.
  • 400 - Malformed RPC, argument type error, etc.
  • 403 - RPC call forbidden.

In this case, "404" would mean that the /api/v0/dns RPC endpoint doesn't exist. 500 means that the function _does_ exist, it just failed internally for some reason. To know that reason, you have to look at the "application layer" error (commands lib error).

@lidel this really should be documented somewhere. Could you try to find a place to put it?

Can we discuss improving this?

If someone implements a fix that actually _works_ reliably, I'd be happy to accept it. However, I'm pretty sure there _is_ no nice solution.

IIRC, there were two key issues:

  1. We'd like some way to distinguish between "command doesn't exist" and "the thing you asked for doesn't exist".
  2. The API supports streaming responses and "late" errors.

For example, a user might call ipfs cat FILE_A FILE_B FILE_C. In this case, we'll fetch the first file, then the second, then the third. If FILE_B doesn't exist, we'll return:

  1. Status 200.
  2. FILE_A.
  3. A trailing header with a JSON-encoded error.

Basically, the only error conditions we can _reliably_ report in the status code are ones related to the RPC layer (endpoint not found, request malformed, etc.).

For some context, I've sunk hundreds of hours into the commands lib and don't want to spend _any_ more time on it unless absolutely necessary. Any work we would put into the commands lib should be put into replacing it.

@olizilla I am also having problems due to 500 (https://github.com/ipfs-shipyard/ipfs-companion/issues/755) but unless you are planning to change status code at nginx level, I don't think we can ship a fix for /api/v0. Like Steven said, better to invest time in https://github.com/ipfs/specs/pull/224 and https://github.com/ipfs/specs/issues/225 and solve this is /api/v1.

@lidel this really should be documented somewhere. Could you try to find a place to put it?

Added to https://docs.ipfs.io/reference/api/http/ in https://github.com/ipfs/http-api-docs/pull/23 / https://github.com/ipfs/docs/pull/368

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ArcticLampyrid picture ArcticLampyrid  路  3Comments

zignig picture zignig  路  3Comments

Kubuxu picture Kubuxu  路  3Comments

whyrusleeping picture whyrusleeping  路  4Comments

lidel picture lidel  路  3Comments