|
| 1 | +/* |
| 2 | + * Copyright (c) "Neo4j" |
| 3 | + * Neo4j Sweden AB [http://neo4j.com] |
| 4 | + * |
| 5 | + * This file is part of Neo4j. |
| 6 | + * |
| 7 | + * Neo4j is free software: you can redistribute it and/or modify |
| 8 | + * it under the terms of the GNU General Public License as published by |
| 9 | + * the Free Software Foundation, either version 3 of the License, or |
| 10 | + * (at your option) any later version. |
| 11 | + * |
| 12 | + * This program is distributed in the hope that it will be useful, |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | + * GNU General Public License for more details. |
| 16 | + * |
| 17 | + * You should have received a copy of the GNU General Public License |
| 18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | + */ |
| 20 | + |
| 21 | +import { ErrorType } from 'services/exceptions' |
| 22 | +import { formatError } from './errorUtils' |
| 23 | + |
| 24 | +describe('error formatting', () => { |
| 25 | + test('formats an error with no gql fields correctly', () => { |
| 26 | + const error = { |
| 27 | + type: 'Neo4jError' as ErrorType, |
| 28 | + message: 'epochSeconds cannot be selected together with datetime.', |
| 29 | + code: 'Neo.ClientError.Statement.ArgumentError' |
| 30 | + } |
| 31 | + |
| 32 | + const result = formatError(5.6, error) |
| 33 | + expect(result).toEqual({ |
| 34 | + description: 'epochSeconds cannot be selected together with datetime.', |
| 35 | + title: 'Neo.ClientError.Statement.ArgumentError' |
| 36 | + }) |
| 37 | + }) |
| 38 | + |
| 39 | + test('formats a long error with no gql fields correctly', () => { |
| 40 | + const error = { |
| 41 | + type: 'Neo4jError' as ErrorType, |
| 42 | + message: |
| 43 | + 'The shortest path algorithm does not work when the start and end nodes are the same. This can happen if you perform a shortestPath search after a cartesian product that might have the same start and end nodes for some of the rows passed to shortestPath. If you would rather not experience this exception, and can accept the possibility of missing results for those rows, disable this in the Neo4j configuration by setting `dbms.cypher.forbid_shortestpath_common_nodes` to false. If you cannot accept missing results, and really want the shortestPath between two common nodes, then re-write the query using a standard Cypher variable length pattern expression followed by ordering by path length and limiting to one result.', |
| 44 | + code: 'Neo.DatabaseError.Statement.ExecutionFailed' |
| 45 | + } |
| 46 | + |
| 47 | + const result = formatError(5.6, error) |
| 48 | + expect(result).toEqual({ |
| 49 | + description: |
| 50 | + 'The shortest path algorithm does not work when the start and end nodes are the same. This can happen if you perform a shortestPath search after a cartesian product that might have the same start and end nodes for some of the rows passed to shortestPath. If you would rather not experience this exception, and can accept the possibility of missing results for those rows, disable this in the Neo4j configuration by setting `dbms.cypher.forbid_shortestpath_common_nodes` to false. If you cannot accept missing results, and really want the shortestPath between two common nodes, then re-write the query using a standard Cypher variable length pattern expression followed by ordering by path length and limiting to one result.', |
| 51 | + title: 'Neo.DatabaseError.Statement.ExecutionFailed' |
| 52 | + }) |
| 53 | + }) |
| 54 | + |
| 55 | + test('formats a gql error correctly', () => { |
| 56 | + const error = { |
| 57 | + type: 'Neo4jError' as ErrorType, |
| 58 | + message: 'Expected parameter(s): param', |
| 59 | + code: 'Neo.ClientError.Statement.ParameterMissing', |
| 60 | + gqlStatus: '42N51', |
| 61 | + gqlStatusDescription: |
| 62 | + 'error: syntax error or access rule violation - invalid parameter. Invalid parameter $`param`.', |
| 63 | + cause: { |
| 64 | + gqlStatus: '22G03', |
| 65 | + gqlStatusDescription: '22G03', |
| 66 | + cause: { |
| 67 | + gqlStatus: '22N27', |
| 68 | + gqlStatusDescription: |
| 69 | + "error: data exception - invalid entity type. Invalid input '******' for $`param`. Expected to be STRING." |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + const result = formatError(5.7, error) |
| 75 | + expect(result).toEqual({ |
| 76 | + description: 'Invalid parameter $`param`.', |
| 77 | + innerError: { |
| 78 | + cause: { |
| 79 | + gqlStatus: '22N27', |
| 80 | + gqlStatusDescription: |
| 81 | + "error: data exception - invalid entity type. Invalid input '******' for $`param`. Expected to be STRING." |
| 82 | + }, |
| 83 | + gqlStatus: '22G03', |
| 84 | + gqlStatusDescription: '22G03' |
| 85 | + }, |
| 86 | + title: '42N51: Syntax error or access rule violation - invalid parameter' |
| 87 | + }) |
| 88 | + }) |
| 89 | + |
| 90 | + test('formats a gql error with no description correctly', () => { |
| 91 | + const error = { |
| 92 | + type: 'Neo4jError' as ErrorType, |
| 93 | + message: 'epochSeconds cannot be selected together with datetime.', |
| 94 | + code: 'Neo.ClientError.Statement.ArgumentError', |
| 95 | + gqlStatus: '22007', |
| 96 | + gqlStatusDescription: |
| 97 | + 'error: data exception - invalid date, time, or datetime format', |
| 98 | + cause: { |
| 99 | + gqlStatus: '22N14', |
| 100 | + gqlStatusDescription: |
| 101 | + "error: data exception - invalid temporal value combination. Cannot select both epochSeconds and 'datetime'." |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + const result = formatError(5.7, error) |
| 106 | + expect(result).toEqual({ |
| 107 | + description: '', |
| 108 | + title: '22007: Data exception - invalid date, time, or datetime format', |
| 109 | + innerError: { |
| 110 | + gqlStatus: '22N14', |
| 111 | + gqlStatusDescription: |
| 112 | + "error: data exception - invalid temporal value combination. Cannot select both epochSeconds and 'datetime'." |
| 113 | + } |
| 114 | + }) |
| 115 | + }) |
| 116 | + |
| 117 | + test('formats a gql error with only a gql status correctly', () => { |
| 118 | + const error = { |
| 119 | + type: 'Neo4jError' as ErrorType, |
| 120 | + message: '', |
| 121 | + code: '', |
| 122 | + gqlStatus: '22G03', |
| 123 | + gqlStatusDescription: '22G03', |
| 124 | + cause: undefined |
| 125 | + } |
| 126 | + |
| 127 | + const result = formatError(5.7, error) |
| 128 | + expect(result).toEqual({ |
| 129 | + description: '', |
| 130 | + title: '22G03', |
| 131 | + innerError: undefined |
| 132 | + }) |
| 133 | + }) |
| 134 | + |
| 135 | + test('formats a gql error with a cause correctly', () => { |
| 136 | + const error = { |
| 137 | + type: 'Neo4jError' as ErrorType, |
| 138 | + message: '', |
| 139 | + code: '', |
| 140 | + gqlStatus: '22N27', |
| 141 | + gqlStatusDescription: |
| 142 | + "error: data exception - invalid entity type. Invalid input '******' for $`param`. Expected to be STRING.", |
| 143 | + cause: undefined |
| 144 | + } |
| 145 | + |
| 146 | + const result = formatError(5.7, error) |
| 147 | + expect(result).toEqual({ |
| 148 | + description: |
| 149 | + "Invalid input '******' for $`param`. Expected to be STRING.", |
| 150 | + title: '22N27: Data exception - invalid entity type', |
| 151 | + innerError: undefined |
| 152 | + }) |
| 153 | + }) |
| 154 | + |
| 155 | + test('formats a long gql error correctly', () => { |
| 156 | + const error = { |
| 157 | + type: 'Neo4jError' as ErrorType, |
| 158 | + message: |
| 159 | + 'The shortest path algorithm does not work when the start and end nodes are the same. This can happen if you perform a shortestPath search after a cartesian product that might have the same start and end nodes for some of the rows passed to shortestPath. If you would rather not experience this exception, and can accept the possibility of missing results for those rows, disable this in the Neo4j configuration by setting `dbms.cypher.forbid_shortestpath_common_nodes` to false. If you cannot accept missing results, and really want the shortestPath between two common nodes, then re-write the query using a standard Cypher variable length pattern expression followed by ordering by path length and limiting to one result.', |
| 160 | + code: 'Neo.DatabaseError.Statement.ExecutionFailed', |
| 161 | + gqlStatus: '51N23', |
| 162 | + gqlStatusDescription: |
| 163 | + "error: system configuration or operation exception - cyclic shortest path search disabled. Cannot find the shortest path when the start and end nodes are the same. To enable this behavior, set 'dbms.cypher.forbid_shortestpath_common_nodes' to false.", |
| 164 | + cause: undefined |
| 165 | + } |
| 166 | + |
| 167 | + const result = formatError(5.7, error) |
| 168 | + expect(result).toEqual({ |
| 169 | + description: |
| 170 | + "Cannot find the shortest path when the start and end nodes are the same. To enable this behavior, set 'dbms.cypher.forbid_shortestpath_common_nodes' to false.", |
| 171 | + title: |
| 172 | + '51N23: System configuration or operation exception - cyclic shortest path search disabled', |
| 173 | + innerError: undefined |
| 174 | + }) |
| 175 | + }) |
| 176 | +}) |
0 commit comments