Header Ads Widget

Ticker

6/recent/ticker-posts

Prácticas recomendadas para el manejo de errores de API


 Los códigos de error son casi lo último que desea ver en una respuesta de API. En términos generales, significa una de dos cosas: algo estaba tan mal en su solicitud o en su manejo que la API simplemente no pudo analizar los datos pasados, o la API en sí tiene tantos problemas que incluso la solicitud mejor formada va fallar. En cualquier situación, el tráfico se detiene y comienza el proceso de descubrir la causa y la solución.

Dicho esto, los errores, ya sea en forma de código o en una simple respuesta de error , son un poco como obtener una oportunidad: desagradables, pero increíblemente útiles. Los códigos de error son probablemente el elemento de diagnóstico más útil en el espacio de las API, y esto es sorprendente, dada la poca atención que les prestamos.

Hoy vamos a hablar sobre exactamente por qué las respuestas a errores y los enfoques de manejo son tan útiles e importantes. Echaremos un vistazo a algunas clasificaciones de códigos de error comunes que encontrará el usuario medio, así como a algunos ejemplos de estos códigos en acción. También hablaremos un poco sobre lo que hace que un código de error sea "bueno" y lo que hace que un código de error sea "malo", y cómo asegurarse de que sus códigos de error estén a la altura.

El valor de los códigos de error

Como ya dijimos, los códigos de error son extremadamente útiles. Los códigos de error en la etapa de respuesta de una API son la forma fundamental en que un desarrollador puede comunicar fallas a un usuario. Esta etapa, que se encuentra después de la etapa de solicitud inicial, es una comunicación directa entre el cliente y la API. A menudo, es el primer y más importante paso para no solo notificar al usuario de una falla, sino también para iniciar el proceso de resolución de errores.

Un usuario no elige cuándo se genera un error o qué error recibe; las situaciones de error a menudo surgen en instancias que, para el usuario, son completamente aleatorias y sospechosas. Por lo tanto, las respuestas a los errores son la única comunicación verdaderamente constante y coherente de la que el usuario puede confiar cuando se produce un error. Los códigos de error tienen un valor implícito en la forma en que aclaran la situación y comunican la funcionalidad prevista .

Considere, por ejemplo, un código de error como "401 no autorizado: pase el token". En tal respuesta, usted comprende el punto de falla, específicamente que el usuario no está autorizado. Sin embargo, además, descubre la funcionalidad deseada: la API requiere un token, y ese token debe pasarse como parte de la solicitud para obtener la autorización.

Con un código de error simple y una explicación de la resolución, no solo ha comunicado la causa del error, sino también la funcionalidad y el método previstos para corregir dicho error, eso es increíblemente valioso, especialmente por la cantidad de datos que realmente se devuelven.

Códigos de estado HTTP

Antes de profundizar en los códigos de error y lo que hace que un código "bueno" sea "bueno", debemos abordar el formato de códigos de estado HTTP. Estos códigos son los códigos de estado más comunes que encontrará el usuario promedio, no solo en términos de API, sino en términos de uso general de Internet. Si bien existen otros protocolos y tienen su propio sistema de códigos, los códigos de estado HTTP dominan la comunicación API y es probable que los códigos específicos del proveedor se deriven de estos rangos.

1XX - Informativo

La gama 1XX tiene dos funcionalidades básicas. El primero es en la transferencia de información relacionada con el estado del protocolo de los dispositivos conectados; por ejemplo, 101 Switching Protocolses un código de estado que indica que el cliente ha solicitado un cambio de protocolo del servidor y que la solicitud ha sido aprobada. El rango 1XX también aclara el estado de la solicitud inicial . 100 Continue, por ejemplo, observa que un servidor ha recibido encabezados de solicitud de un cliente y que el servidor está esperando el cuerpo de la solicitud.

2XX - Éxito

La gama 2XX señala una serie de éxitos en la comunicación y agrupa varias respuestas en códigos específicos. Los primeros tres códigos de estado demuestran perfectamente este rango: 200 OKsignifica que una solicitud GET o POST fue exitosa, 201 Createdconfirma que se ha cumplido una solicitud y se ha creado un nuevo recurso para el cliente, y 202 Acceptedsignifica que la solicitud ha sido aceptada y ese procesamiento ha comenzado.

3XX - Redirección

El rango 3XX tiene que ver con el estado del recurso o punto final . Cuando se envía este tipo de código de estado, significa que el servidor aún acepta la comunicación, pero que el punto contactado no es el punto correcto de entrada al sistema. 301 Moved Permanentlyverifica que la solicitud del cliente de hecho llegó al sistema correcto, pero que esta solicitud y todas las solicitudes futuras deben ser manejadas por un URI diferente. Esto es muy útil en subdominios y cuando se mueve un recurso de un servidor a otro.

4XX - Error del cliente

La serie 4XX de códigos de error es quizás la más famosa debido al 404 Not Foundestado icónico , que es un marcador bien conocido para las URL y URI que están formadas incorrectamente. Sin embargo, existen otros códigos de estado más útiles para las API en este rango.

414 URI Too Longes un código de estado común, que indica que los datos enviados en una solicitud GET son demasiado largos y deben convertirse en una solicitud POST. Otro código común es 429 Too many Requests, que se usa para limitar la velocidad para notar que un cliente está intentando demasiadas solicitudes a la vez y que su tráfico está siendo rechazado.

5XX - Error del servidor

Finalmente, el rango 5XX está reservado para códigos de error relacionados específicamente con la funcionalidad del servidor . Mientras que el rango 4XX es responsabilidad del cliente (y por lo tanto denota una falla del cliente), el rango 5XX señala específicamente fallas con el servidor. Los códigos de error como 502 Bad Gateway, que indican que el servidor de subida ha fallado y que el servidor actual es una puerta de enlace, exponen aún más la funcionalidad del servidor como un medio para mostrar dónde está ocurriendo la falla. También hay fallas generales menos específicas, como 503 Service Unavailable.

Hacer un buen código de error

Con un conocimiento sólido de los códigos de estado HTTP, podemos comenzar a analizar lo que realmente hace que un código de error sea bueno y lo que lo convierte en un código de error malo. Los códigos de error de calidad no solo comunican lo que salió mal, sino también por qué salió mal.

Los códigos de error demasiado opacos son extremadamente inútiles. Imaginemos que está intentando realizar una solicitud GET a una API que maneja el inventario de música digital. Ha enviado su solicitud a una API que sabe que acepta habitualmente su tráfico, ha pasado las credenciales de autenticación y autorización correctas y, según su leal saber y entender, el servidor está listo para responder.

Envías tus datos y recibes el siguiente código de error - 400 Bad RequestSin datos adicionales, sin más información, ¿qué te dice esto realmente? Está en el rango 4XX, por lo que sabe que el problema estaba en el lado del cliente, pero no hace absolutamente nada para comunicar el problema en sí más que "solicitud incorrecta".

Esto es cuando un código de error "funcional" realmente no es tan funcional como debería ser. Esa misma respuesta podría ser fácilmente útil y transparente con un mínimo esfuerzo, pero ¿qué implicaría esto? Los buenos códigos de error deben pasar tres criterios básicos para ser realmente útiles. Un código de error de calidad debe incluir:

  • Un código de estado HTTP , para que el origen y el ámbito del problema se puedan determinar con facilidad;
  • Un ID de referencia interno para la notación de errores específica de la documentación. En algunos casos, esto puede reemplazar el código de estado HTTP, siempre que la hoja de referencia interna incluya el esquema del código de estado HTTP o material de referencia similar.
  • Mensajes legibles por humanos que resumen el contexto, la causa y la solución general del error en cuestión.

Incluir códigos de estado estandarizados

En primer lugar, cada código de error generado debe tener un código de estado adjunto. Si bien esto a menudo toma la forma de un código interno, generalmente toma la forma de un código de estado estandarizado en el esquema de código de estado HTTP. Al observar el estado utilizando esta estandarización muy específica, no solo comunica el tipo de error, sino que comunica dónde ha ocurrido ese error.

Existen ciertas implicaciones para cada uno de los rangos de código de estado HTTP, y estas implicaciones dan un sentido de la responsabilidad de dicho error. Los errores 5XX, por ejemplo, tenga en cuenta que el error se genera desde el servidor y que la corrección es necesariamente algo que ver con los datos relacionados con el servidor, el direccionamiento, etc. solicitud del cliente o el estado del cliente en ese momento.

Al abordar los códigos de error utilizando un estado predeterminado , puede proporcionar un punto de partida muy útil para que incluso los usuarios básicos solucionen sus errores.

Dar contexto

En primer lugar, un código de error debe dar contexto . En nuestro ejemplo anterior, 400 Bad Requestno significa nada. En cambio, un código de error debería proporcionar más contexto. Una forma de hacerlo es pasando esta información en el cuerpo de la respuesta en el lenguaje que es común a la solicitud en sí.

Por ejemplo, nuestro código de error 400 Bad Requestpuede tener fácilmente un cuerpo JSON que brinda mucha más información útil al cliente:


< HTTP/1.1 400 Bad Request
< Date: Wed, 31 May 2017 19:01:41 GMT
< Server: Apache/2.4.25 (Ubuntu)
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: application/json
{ "error" : "REQUEST - BR0x0071" }

Este código de error es bueno, pero no excelente. ¿Qué hace bien? Bueno, proporciona contexto, para empezar. Poder ver cuál es el tipo específico de falla muestra dónde el usuario puede comenzar el proceso de resolución de problemas. Además, y de manera vital, también proporciona un ID de referencia interno en forma de “BR0x0071”, al que se puede hacer referencia internamente.

Si bien este es un código de error aceptable, solo cumple con una fracción de nuestros requisitos.

Legibilidad humana

Parte de lo que hace que los códigos de error como el que acabamos de crear sean tan poderosos es que los humanos y las máquinas pueden utilizarlos por igual. Desafortunadamente, esto es una cosa muy fácil de estropear: los códigos de error generalmente son manejados por máquinas, por lo que es muy tentador simplemente codificar para la aplicación en lugar de para el usuario de dicha aplicación.

En nuestro ejemplo recién formado, tenemos un error muy claro que manejar, pero tenemos un problema adicional. Si bien hemos agregado contexto, ese contexto está en forma de código de referencia legible por máquina a una nota de error interna. El usuario tendría que encontrar la documentación, buscar el código de solicitud “BRx0071” y luego averiguar qué salió mal.

Hemos caído en la trampa de codificar la máquina . Si bien nuestro código es sucinto y útil en la medida en que proporciona contexto, lo hace a costa de la legibilidad humana . Con algunos ajustes, podríamos mejorar el código, sin dejar de proporcionar el número de referencia como lo hicimos antes:


< HTTP/1.1 400 Bad Request
< Date: Wed, 31 May 2017 19:01:41 GMT
< Server: Apache/2.4.25 (Ubuntu)
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: application/json
{ "error" : "Bad Request - Your request is missing parameters. Please verify and resubmit. Issue Reference Number BR0x0071" }


Con esta respuesta, no solo obtiene el código de estado, sino que también obtiene información útil y procesable . En este caso, le dice al usuario que el problema está dentro de sus parámetros. Esto al menos ofrece un lugar para comenzar a solucionar problemas y es mucho más útil que decir "hay un problema".

Si bien aún desea proporcionar el número de referencia del problema, especialmente si tiene la intención de integrar un rastreador de problemas en su ciclo de desarrollo, el error real en sí es mucho más poderoso y mucho más efectivo que simplemente disparar un montón de datos al usuario de la aplicación y esperando que algo se pegue.

Buenos ejemplos de errores

Echemos un vistazo a algunas impresionantes implementaciones de códigos de error en algunos sistemas populares.

Gorjeo

La API de Twitter es un gran ejemplo de códigos descriptivos de informes de errores. Intentemos enviar una solicitud GET para recuperar nuestra línea de tiempo de menciones.

https://api.twitter.com/1.1/statuses/mentions_timeline.json

Cuando esto se envía a la API de Twitter, recibimos la siguiente respuesta:

HTTP/1.1 400 Bad Request
x-connection-hash: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx set-cookie: guest_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Date: Thu, 01 Jun 2017 03:04:23 GMT Content-Length: 62 x-response-time: 5 strict-transport-security: max-age=631138519 Connection: keep-alive Content-Type: application/json; charset=utf-8 Server: tsa_b {"errors":[{"code":215,"message":"Bad Authentication data."}]}

Al observar estos datos, generalmente podemos averiguar cuál es nuestro problema. Primero, se nos dice que hemos enviado un 400 Bad RequestEsto nos dice que el problema está en alguna parte de nuestra solicitud. La longitud de nuestro contenido es aceptable y nuestro tiempo de respuesta está dentro de los límites normales. Sin embargo, podemos ver que estamos recibiendo un código de error único que el propio Twitter ha indicado: "215", con un mensaje adjunto que dice "Datos de autenticación incorrectos".

Este código de error proporciona información valiosa sobre por qué se produjo el error y también cómo corregirlo. Nuestro error radica en el hecho de que no pasamos ningún dato de autenticación en absoluto; en consecuencia, se hace referencia al error 215, que nos dice que la solución es proporcionar dichos datos de autenticación, pero también nos da un número de referencia en la documentación interna de Twitter. API.

Facebook

Para otro gran ejemplo, veamos otra red social. La API Graph de Facebook nos permite hacer muchas cosas siempre que tengamos los datos de autenticación adecuados. A los efectos de este artículo, toda la información personal se borrará por motivos de seguridad.

Primero, pasemos una solicitud GET para determinar algunos detalles sobre un usuario:

https://graph.facebook.com/v2.9/me?fields=id%2Cname%2Cpicture%2C%20picture&access_token=xxxxxxxxxxx

Esta solicitud debe proporcionarnos algunos campos básicos del perfil de Facebook de este usuario, incluida la identificación, el nombre y la imagen. En cambio, obtenemos esta respuesta de error:

{
"error": { "message": "Syntax error \"Field picture specified more than once. This is only possible before version 2.1\" at character 23: id,name,picture,picture", "type": "OAuthException", "code": 2500, "fbtrace_id": "xxxxxxxxxxx" }
}

Si bien Facebook no pasa directamente el código de error HTTP en el cuerpo, sí pasa mucha información útil. El área de "mensaje" señala que nos hemos encontrado con un error de sintaxis, específicamente que hemos definido el campo "imagen" más de una vez. Adicionalmente, este campo nos permite saber que este comportamiento era posible en versiones anteriores, lo cual es una herramienta muy útil para comunicar a los usuarios un cambio de comportamiento de versiones anteriores a la actual.

Además, se nos proporciona un código y otro fbtrace_idque se puede utilizar con soporte para identificar problemas específicos en casos más complejos. También hemos recibido un tipo de error específico, en este caso OAuthException, que se puede utilizar para reducir aún más los detalles del caso.

Bing

Para mostrar un código de respuesta de falla complejo, enviemos una solicitud GET mal formada (esencialmente nula) a Bing.

HTTP/1.1 200
Date:
Thu, 01 Jun 2017 03:40:55 GMT
Content-Length:
276
Connection:
keep-alive
Content-Type:
application/json; charset=utf-8
Server:
Microsoft-IIS/10.0
X-Content-Type-Options:
nosniff
 
{"SearchResponse":{"Version":"2.2","Query":{"SearchTerms":"api error codes"},"Errors":[{"Code":1001,"Message":"Required parameter is missing.","Parameter":"SearchRequest.AppId","HelpUrl":"http\u003a\u002f\u002fmsdn.microsoft.com\u002fen-us\u002flibrary\u002fdd251042.aspx"}]}}

Este es un código de error muy bueno, quizás el mejor de los tres que hemos demostrado aquí. Si bien tenemos el código de error en forma de "1001", también tenemos un mensaje que indica que falta un parámetro. Este parámetro se indica específicamente como "SearchRequestAppId" y se pasa una variable "HelpUrl" como un enlace a una solución.

En este caso, tenemos lo mejor de todos los mundos. Tenemos un código de error legible por máquina, un resumen legible por humanos y una explicación directa tanto del error en sí como de dónde encontrar más información sobre el error.

Spotify

Aunque los errores 5XX son algo raros en los entornos de producción modernos, tenemos algunos ejemplos en los sistemas de informes de errores. Uno de esos informes señaló un error 5XX generado a partir de la siguiente llamada:

GET /v1/me/player/currently-playing

Esto resultó en el siguiente error:

[2017-05-02 13:32:14] production.ERROR: GuzzleHttp\Exception\ServerException: Server error: `GET https://api.spotify.com/v1/me/player/currently-playing` resulted in a `502 Bad Gateway` response:
{ "error" : { "status" : 502, "message" : "Bad gateway." } }

Entonces, ¿qué hace que este sea un buen código de error? Si bien el error 502 Bad gateway parece opaco, los datos adicionales en la respuesta del encabezado es de donde se deriva nuestro valor. Al observar el error que se produce en la producción y su variable abordada, tenemos una sensación general de que el problema en cuestión es que la puerta de enlace del servidor maneja una excepción en lugar de algo externo al servidor. En otras palabras, sabemos que la solicitud ingresó al sistema, pero fue rechazada por un problema interno en esa dirección de excepción específica.

Al abordar este problema, se observó que los errores 502 no son anormales, lo que sugiere que se trata de un problema con la carga del servidor o los tiempos de espera de la puerta de enlace. En tal caso, es casi imposible anotar de manera granular todas las variables posibles; dada esa situación, este código de error es lo mejor que podría pedir.

Conclusión

Gran parte de la estructura de un código de error es estilística . La forma en que hace referencia a los enlaces, el código de error que genera y la forma de mostrar esos códigos está sujeto a cambios de una empresa a otra. Sin embargo, se ha avanzado en la estandarización de estos enfoques; el IETF publicó recientemente RFC 7807 , que describe cómo usar un objeto JSON como una forma de modelar los detalles del problema dentro de la respuesta HTTP. La idea es que al proporcionar mensajes legibles por máquina más específicos con una respuesta de error, los clientes de la API pueden reaccionar a los errores de manera más efectiva.

En general, el objetivo de las respuestas de error es crear una fuente de información no solo para informar al usuario de un problema, sino también de la solución a ese problema. El simple hecho de indicar un problema no hace nada para solucionarlo, y lo mismo ocurre con las fallas de API.

El equilibrio, entonces, es de usabilidad y brevedad. Ser capaz de describir completamente el problema en cuestión y presentar una solución utilizable debe equilibrarse con facilidad de lectura y análisis. Cuando se logra ese equilibrio perfecto, sucede algo realmente poderoso.

Si bien puede parecer extraño hablar filosóficamente sobre los códigos de error, son una herramienta verdaderamente poderosa que se subutiliza en gran medida. Incorporarlos en su código no solo es bueno para la experiencia empresarial y del desarrollador de API, sino que puede conducir a una experiencia del usuario final más positiva, impulsando la adopción y el uso continuos.

Publicar un comentario

0 Comentarios