Recientemente me encontraba desarrollando una funcionalidad la cual se encarga de subir archivos a la nube en Node 14, un proceso “sencillo” entre comillas, el reto era principalmente una validación a una url devuelta por la funcionalidad de subir archivos, a este había que hacer un get y “atrapar” el estatus que tenga, un 200 en caso ok o un 400 en un caso error.
El flujo podría ser algo como esto:
No soy fan de instalarme una dependencia (axios, request, etc.) por casos como este que puede hacerse con algo de manera nativa con un poco más de esfuerzo, así que me fui por utilizar https.
El código es el siguiente:
const https = require('https');
const request = https.get(
`https://storage.googleapis.com${response.path}`,
(res) => {
console.log(res.statusCode);
},
);
request.on('error', (error) => {
console.log(error);
});
request.end();
Si bien vemos, solo hace un get a la url de Google Cloud Storage y al path devuelto por la funcionalidad de subir:
`https://storage.googleapis.com${response.path}`
El objeto response tiene algunos atributos como estos:
{
path: "/3248902348/image.jpg",
content_type: "image/jpg",
cloud_id: "12392103921",
…etc,
}
Un event que se gatilla al error
request.on('error', (error) => {
console.log(error);
});
Y la finalización del request
request.end();
Si bien este código que se podría casi “copypastear” funciona, en el flujo planteado algo anda mal, al ejecutarlo no esperamos la respuesta positiva o negativa del request y se continúa la ejecución del script, algo que me pareció interesante es que la respuesta la tenía en la mente, pero si fuera recién iniciando en el mundo de javascript, es decir, mi yo de hace unos años, este problema hubiera sido un dolor de cabeza.
Las promesas
La solución, encapsular en una promesa este bloque de código.
const requestValidate = (response) => {
const https = require('https');
return new Promise((resolve) => {
const request = https.get(
`https://storage.googleapis.com${response.path}`,
(res) => {
resolve(res.statusCode);
},
);
request.on('error', (error) => {
resolve(400);
});
request.end();
});
};
Claro esta, es una promesa sin ninguna exception y es algo que personalmente me gusta, la flexibilidad de las promesas y no siempre tener que mandar errores por todos lados, así cuando queramos validar será algo como esto:
const status = await requestValidate(response);
if (status === 400) {
// enviar error y terminar
}
// continuar con lo siguiente
A mi me parece super limpio, algo que me arruinaría sería andar metiendo try, catch, callback hell, etc. para esta validación.
¿Te parece interesante?