Em blogs anteriores, abordamos a execução do N1QL a partir do JavaScript funções, processamento de documentos por meio de iteradorese manipulação de dados.
Passamos agora a tratar os erros dos comandos N1QL.
Tratamento de erros
Quando um erro de qualquer natureza é encontrado, o jsevaluator por padrão, interromperá a execução da função e retornará um erro:

Nesse caso específico, o segundo INSERT falhará porque a chave k10 já 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 |
[ { "code": 10109, "msg": "Error executing function 'doInsert' (n1ql:doInsert)", "reason": { "details": { "Code": " var q2 = N1QL('insert into b1 values(\\\"k10\\\", {\\\"f1\\\": 10});', {}, true);", "Exception": { "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 }, "Location": "functions/n1ql.js:21", "Stack": " at doInsert (functions/n1ql.js:3:14)" }, "type": "Exceptions from JS code" } } ] |
Você não precisa se ater ao comportamento padrão, pois o JavaScript permite capturar erros e lidar com eles:

Nesse caso, a função doInsert() retornos falha porque a chave k10 já existe.
Retorno vs. arremesso
O captura pode ser usado para tratar a falha da maneira que for útil para sua lógica comercial.
As opções disponíveis se resumem a 1) tomar alguma ação evasiva e continuar a execução, 2) retornar mais cedo com sucesso e 3) retornar mais cedo com falha.
A diferença entre o sucesso e o fracasso é simplesmente usar retorno para retornar um valor como no exemplo acima vs lançar para retornar um erro.

A diferença entre os dois é importante, pois se você optar por retornar um resultado, a solicitação do chamador continuará a execução. Por outro lado, se você lançar um erro, toda a solicitação falhará com o erro, portanto, tenha cuidado com o que deseja usar, pois isso fará a diferença entre o funcionamento correto e o mau funcionamento da solicitação.
Expressão retornada
A segunda coisa a ter em mente é que, independentemente de retornar ou lançar um erro, você pode muito bem querer fornecer informações significativas.
Considere o código a seguir:

Isso falhará com 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 |
[ { "code": 10109, "msg": "Error executing function 'doInsert' (n1ql:doInsert)", "reason": { "details": { "Code": " throw err;", "Exception": { "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 }, "Location": "functions/n1ql.js:6", "Stack": " at doInsert (functions/n1ql.js:3:17)" }, "type": "Exceptions from JS code" } } ] |
Assim como no exemplo anterior, o que concluímos disso é que erro é um objeto e é retornado no razão campo.
No entanto, se você alterar o lançar declaração dessa forma:

O doInsert() agora lançará uma string e não um objeto:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[ { "code": 10109, "msg": "Error executing function 'doInsert' (n1ql:doInsert)", "reason": { "details": { "Code": " throw \"failure\" + err;", "Exception": "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}", "Location": "functions/n1ql.js:6" }, "type": "Exceptions from JS code" } } ] |
O erro agora é transformado em uma cadeia de caracteres e, de repente, seu erro não é tão legível.
Isso se aplica a retorno também: em particular, por padrão erro contém cadeias de caracteres que contêm objetos JSON manipulados.
Por exemplo:

Devoluções:
|
1 2 3 4 5 6 |
[ { "message": "{\"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}", "stack": "Error\n at doInsert (functions/n1ql.js:3:17)" } ] |
Se você quiser obter um bom valor retornado, terá que analisar o error.message antes de devolvê-lo:

O que resulta em:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[ { "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 } ] |
E se você quiser incluir a pilha também, terá que construir um novo objeto da seguinte forma:

Wque produz:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[ { "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, "stack": "Error\n at doInsert (functions/n1ql.js:3:17)" } ] |
A moral da história é: tenha cuidado com a forma como você retorna seu erro e tenha cuidado com a forma como você o formata.
Conclusão
Ao longo de vários blogs, abordamos a execução do N1QL, o processamento de documentos e a manipulação de dados, além do tratamento de erros.
Na próxima parte da série, passaremos às declarações preparadas.