En blogs anteriores, hemos cubierto la ejecución de N1QL desde JavaScript funcionesTramitación de documentos a través de iteradoresy manipulación de datos.
Ahora pasamos a manejar los errores de las sentencias N1QL.
Tratamiento de errores
Cuando se produce un error de cualquier naturaleza, el jsevaluator por defecto detendrá la ejecución de la función y devolverá un error:

En este caso concreto, el segundo INSERT fallará porque la clave k10 ya existe:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[ { "código": 10109, "msg": "Error al ejecutar la función 'doInsert' (n1ql:doInsert)", "razón": { "detalles": { "Código": " var q2 = N1QL('insert into b1 values(\\\"k10\\\", {\\\"f1\\\": 10});', {}, true);", "Excepción": { "llamante": "couchbase:2088", "causa": { "llamante": "couchbase:1961", "código": 17012, "llave": "dml.statement.duplicatekey", "mensaje": "Clave duplicada: k10" }, "código": 12009, "icausa": "Clave duplicada: k10", "llave": "datastore.couchbase.DML_error", "mensaje": "Error DML, las posibles causas incluyen modificación concurrente. Error al realizar INSERT en la clave k10", "reintentar": falso }, "Localización": "functions/n1ql.js:21", "Pila": " at doInsert (functions/n1ql.js:3:14)" }, "tipo": "Excepciones del código JS" } } ] |
No tienes que ceñirte al comportamiento por defecto, JavaScript permite capturar errores y manejarlos:

En este caso, la función doInsert() devuelve fallo porque clave k10 ya existe.
Retorno vs lanzamiento
En captura se puede utilizar para manejar el fallo de cualquier manera que sea útil para su lógica de negocio.
Las opciones disponibles se reducen a 1) tomar alguna acción evasiva y continuar la ejecución, 2) regresar antes de tiempo con éxito, y 3) regresar antes de tiempo con fracaso.
La diferencia entre el éxito y el fracaso es simplemente utilizar devolver para devolver un valor como en el ejemplo anterior vs tirar para devolver un error.

La diferencia entre ambos es importante, porque si decide devolver un resultado, la petición de llamada continuará su ejecución. Mientras que si lanza un error, toda la petición fallará con el error, así que tenga en cuenta cuál quiere usar, porque marcará la diferencia entre que su petición funcione correctamente o se comporte mal.
Expresión devuelta
Lo segundo que hay que tener en cuenta es que, tanto si devuelve como si lanza un error, es muy posible que quiera dar información significativa.
Considere el siguiente código:

Esto fallará con algo como:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
[ { "código": 10109, "msg": "Error al ejecutar la función 'doInsert' (n1ql:doInsert)", "razón": { "detalles": { "Código": "throw err;", "Excepción": { "llamante": "couchbase:2088", "causa": { "llamante": "couchbase:1961", "código": 17012, "llave": "dml.statement.duplicatekey", "mensaje": "Clave duplicada: k10" }, "código": 12009, "icausa": "Clave duplicada: k10", "llave": "datastore.couchbase.DML_error", "mensaje": "Error DML, las posibles causas incluyen modificación concurrente. Error al realizar INSERT en la clave k10", "reintentar": falso }, "Localización": "functions/n1ql.js:6", "Pila": " at doInsert (functions/n1ql.js:3:17)" }, "tipo": "Excepciones del código JS" } } ] |
Al igual que en el ejemplo anterior, lo que se deduce es que err es un objeto, y se devuelve en motivo campo.
Sin embargo, si modifica el tirar declaración así:

En doInsert() lanzará ahora una cadena y no un objeto:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[ { "código": 10109, "msg": "Error al ejecutar la función 'doInsert' (n1ql:doInsert)", "razón": { "detalles": { "Código": "throw \"fallo\" + err;", "Excepción": "failure {\"caller\":\"couchbase:2088\",\"cause\":{\"caller\":\"couchbase:1961\",\"code\":17012,\"key\":\"dml.statement.duplicatekey\",\"message\":\"Duplicate Key: k10\"},\"code\":12009,\"icause\":\"Duplicate Key: k10\",\"key\":\"datastore.couchbase.DML_error",\"message\":\"DML Error, possible causes include concurrent modification. Failed to perform INSERT on key k10\",\"retry":false}", "Localización": "functions/n1ql.js:6" }, "tipo": "Excepciones del código JS" } } ] |
En err se convierte en una cadena y, de repente, el error no es tan legible.
Esto se aplica a devolver en particular, por defecto err contiene cadenas que contienen objetos JSON marshalled.
Por ejemplo:

Devoluciones:
|
1 2 3 4 5 6 |
[ { "mensaje": "{\"caller\":\"couchbase:2088\",\"cause\":{\"caller\":\"couchbase:1961\",\"code\":17012,\"key\":\"dml.statement.duplicatekey\",\"message\":\"Duplicate Key: k10\"},\"code\":12009,\"icause\":\"Duplicate Key: k10\",\"key\":\"datastore.couchbase.DML_error",\"message\":\"DML Error, possible causes include concurrent modification. Failed to perform INSERT on key k10\",\"retry":false}", "pila": "Error en doInsert (functions/n1ql.js:3:17)" } ] |
Si desea obtener un valor devuelto agradable, tiene que analizar el archivo mensaje.error antes de devolverlo:

Que rinde:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[ { "llamante": "couchbase:2088", "causa": { "llamante": "couchbase:1961", "código": 17012, "llave": "dml.statement.duplicatekey", "mensaje": "Clave duplicada: k10" }, "código": 12009, "icausa": "Clave duplicada: k10", "llave": "datastore.couchbase.DML_error", "mensaje": "Error DML, las posibles causas incluyen modificación concurrente. Error al realizar INSERT en la clave k10", "reintentar": falso } ] |
Y si quieres incluir también la pila, tienes que construir un nuevo objeto así:

Wque produce:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[ { "llamante": "couchbase:2088", "causa": { "llamante": "couchbase:1961", "código": 17012, "llave": "dml.statement.duplicatekey", "mensaje": "Clave duplicada: k10" }, "código": 12009, "icausa": "Clave duplicada: k10", "llave": "datastore.couchbase.DML_error", "mensaje": "Error DML, las posibles causas incluyen modificación concurrente. Error al realizar INSERT en la clave k10", "reintentar": falso, "pila": "Error en doInsert (functions/n1ql.js:3:17)" } ] |
La moraleja de la historia es: ten cuidado con cómo devuelves el error, y ten cuidado con cómo lo formateas.
Conclusión
A lo largo de varios blogs, hemos cubierto la ejecución de N1QL, el procesamiento de documentos y la manipulación de datos, y el manejo de errores.
A continuación hablaremos de las declaraciones preparadas.