(
key: string | number,
collectionId: string,
options?: {
hasCustomGetKey?: boolean
hasJoins?: boolean
hasDistinct?: boolean
},
)
| 170 | |
| 171 | export class DuplicateKeySyncError extends CollectionOperationError { |
| 172 | constructor( |
| 173 | key: string | number, |
| 174 | collectionId: string, |
| 175 | options?: { |
| 176 | hasCustomGetKey?: boolean |
| 177 | hasJoins?: boolean |
| 178 | hasDistinct?: boolean |
| 179 | }, |
| 180 | ) { |
| 181 | const baseMessage = `Cannot insert document with key "${key}" from sync because it already exists in the collection "${collectionId}"` |
| 182 | |
| 183 | // Provide enhanced guidance when custom getKey is used with distinct |
| 184 | if (options?.hasCustomGetKey && options.hasDistinct) { |
| 185 | super( |
| 186 | `${baseMessage}. ` + |
| 187 | `This collection uses a custom getKey with .distinct(). ` + |
| 188 | `The .distinct() operator deduplicates by the ENTIRE selected object (standard SQL behavior), ` + |
| 189 | `but your custom getKey extracts only a subset of fields. This causes multiple distinct rows ` + |
| 190 | `(with different values in non-key fields) to receive the same key. ` + |
| 191 | `To fix this, either: (1) ensure your SELECT only includes fields that uniquely identify each row, ` + |
| 192 | `(2) use .groupBy() with min()/max() aggregates to select one value per group, or ` + |
| 193 | `(3) remove the custom getKey to use the default key behavior.`, |
| 194 | ) |
| 195 | } else if (options?.hasCustomGetKey && options.hasJoins) { |
| 196 | // Provide enhanced guidance when custom getKey is used with joins |
| 197 | super( |
| 198 | `${baseMessage}. ` + |
| 199 | `This collection uses a custom getKey with joined queries. ` + |
| 200 | `Joined queries can produce multiple rows with the same key when relationships are not 1:1. ` + |
| 201 | `Consider: (1) using a composite key in your getKey function (e.g., \`\${item.key1}-\${item.key2}\`), ` + |
| 202 | `(2) ensuring your join produces unique rows per key, or (3) removing the custom getKey ` + |
| 203 | `to use the default composite key behavior.`, |
| 204 | ) |
| 205 | } else { |
| 206 | super(baseMessage) |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | export class MissingUpdateArgumentError extends CollectionOperationError { |
nothing calls this directly
no outgoing calls
no test coverage detected