Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: gajus/slonik
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v31.2.6
Choose a base ref
...
head repository: gajus/slonik
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v31.3.0
Choose a head ref
  • 4 commits
  • 10 files changed
  • 1 contributor

Commits on Oct 10, 2022

  1. Copy the full SHA
    a49c6a8 View commit details
  2. Copy the full SHA
    b8b2efe View commit details
  3. Copy the full SHA
    4aea38f View commit details
  4. feat: add values to error

    gajus committed Oct 10, 2022
    Copy the full SHA
    db39512 View commit details
6 changes: 3 additions & 3 deletions src/connectionMethods/anyFirst.ts
Original file line number Diff line number Diff line change
@@ -11,10 +11,10 @@ import {
any,
} from './any';

export const anyFirst: InternalQueryMethod = async (log, connection, clientConfigurationType, slonikSql, inheritedQueryId) => {
export const anyFirst: InternalQueryMethod = async (log, connection, clientConfigurationType, query, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const rows = await any(log, connection, clientConfigurationType, slonikSql, queryId);
const rows = await any(log, connection, clientConfigurationType, query, queryId);

if (rows.length === 0) {
return [];
@@ -29,7 +29,7 @@ export const anyFirst: InternalQueryMethod = async (log, connection, clientConfi
queryId,
}, 'result row has no columns');

throw new DataIntegrityError();
throw new DataIntegrityError(query);
}

const firstColumnName = keys[0];
8 changes: 4 additions & 4 deletions src/connectionMethods/exists.ts
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import {
query,
} from './query';

export const exists: InternalQueryMethod<Promise<boolean>> = async (log, connection, clientConfiguration, slonikSql, inheritedQueryId) => {
export const exists: InternalQueryMethod<Promise<boolean>> = async (log, connection, clientConfiguration, slonikQuery, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const {
@@ -22,8 +22,8 @@ export const exists: InternalQueryMethod<Promise<boolean>> = async (log, connect
connection,
clientConfiguration,
{
sql: 'SELECT EXISTS(' + slonikSql.sql + ')',
values: slonikSql.values,
sql: 'SELECT EXISTS(' + slonikQuery.sql + ')',
values: slonikQuery.values,
} as TaggedTemplateLiteralInvocation,
queryId,
);
@@ -33,7 +33,7 @@ export const exists: InternalQueryMethod<Promise<boolean>> = async (log, connect
queryId,
}, 'DataIntegrityError');

throw new DataIntegrityError();
throw new DataIntegrityError(slonikQuery);
}

return Boolean((rows[0] as Record<string, unknown>).exists);
6 changes: 3 additions & 3 deletions src/connectionMethods/many.ts
Original file line number Diff line number Diff line change
@@ -16,19 +16,19 @@ import {
*
* @throws NotFoundError If query returns no rows.
*/
export const many: InternalQueryMethod = async (log, connection, clientConfiguration, slonikSql, inheritedQueryId) => {
export const many: InternalQueryMethod = async (log, connection, clientConfiguration, slonikQuery, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const {
rows,
} = await query(log, connection, clientConfiguration, slonikSql, queryId);
} = await query(log, connection, clientConfiguration, slonikQuery, queryId);

if (rows.length === 0) {
log.error({
queryId,
}, 'NotFoundError');

throw new NotFoundError();
throw new NotFoundError(slonikQuery);
}

return rows;
8 changes: 4 additions & 4 deletions src/connectionMethods/manyFirst.ts
Original file line number Diff line number Diff line change
@@ -11,17 +11,17 @@ import {
many,
} from './many';

export const manyFirst: InternalQueryMethod = async (log, connection, clientConfigurationType, slonikSql, inheritedQueryId) => {
export const manyFirst: InternalQueryMethod = async (log, connection, clientConfigurationType, query, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const rows = await many(log, connection, clientConfigurationType, slonikSql, queryId);
const rows = await many(log, connection, clientConfigurationType, query, queryId);

if (rows.length === 0) {
log.error({
queryId,
}, 'DataIntegrityError');

throw new DataIntegrityError();
throw new DataIntegrityError(query);
}

const keys = Object.keys(rows[0] as Record<string, unknown>);
@@ -31,7 +31,7 @@ export const manyFirst: InternalQueryMethod = async (log, connection, clientConf
queryId,
}, 'DataIntegrityError');

throw new DataIntegrityError();
throw new DataIntegrityError(query);
}

const firstColumnName = keys[0];
6 changes: 3 additions & 3 deletions src/connectionMethods/maybeOne.ts
Original file line number Diff line number Diff line change
@@ -16,12 +16,12 @@ import {
*
* @throws DataIntegrityError If query returns multiple rows.
*/
export const maybeOne: InternalQueryMethod = async (log, connection, clientConfiguration, slonikSql, inheritedQueryId) => {
export const maybeOne: InternalQueryMethod = async (log, connection, clientConfiguration, slonikQuery, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const {
rows,
} = await query(log, connection, clientConfiguration, slonikSql, queryId);
} = await query(log, connection, clientConfiguration, slonikQuery, queryId);

if (rows.length === 0) {
return null;
@@ -32,7 +32,7 @@ export const maybeOne: InternalQueryMethod = async (log, connection, clientConfi
queryId,
}, 'DataIntegrityError');

throw new DataIntegrityError();
throw new DataIntegrityError(slonikQuery);
}

return rows[0];
6 changes: 3 additions & 3 deletions src/connectionMethods/maybeOneFirst.ts
Original file line number Diff line number Diff line change
@@ -17,14 +17,14 @@ import {
*
* @throws DataIntegrityError If query returns multiple rows.
*/
export const maybeOneFirst: InternalQueryMethod = async (log, connection, clientConfiguration, slonikSql, inheritedQueryId) => {
export const maybeOneFirst: InternalQueryMethod = async (log, connection, clientConfiguration, query, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const row = await maybeOne(
log,
connection,
clientConfiguration,
slonikSql,
query,
queryId,
);

@@ -39,7 +39,7 @@ export const maybeOneFirst: InternalQueryMethod = async (log, connection, client
queryId,
}, 'DataIntegrityError');

throw new DataIntegrityError();
throw new DataIntegrityError(query);
}

return row[keys[0]];
8 changes: 4 additions & 4 deletions src/connectionMethods/one.ts
Original file line number Diff line number Diff line change
@@ -18,27 +18,27 @@ import {
* @throws NotFoundError If query returns no rows.
* @throws DataIntegrityError If query returns multiple rows.
*/
export const one: InternalQueryMethod = async (log, connection, clientConfiguration, slonikSql, inheritedQueryId) => {
export const one: InternalQueryMethod = async (log, connection, clientConfiguration, slonikQuery, inheritedQueryId) => {
const queryId = inheritedQueryId ?? createQueryId();

const {
rows,
} = await query(log, connection, clientConfiguration, slonikSql, queryId);
} = await query(log, connection, clientConfiguration, slonikQuery, queryId);

if (rows.length === 0) {
log.error({
queryId,
}, 'NotFoundError');

throw new NotFoundError();
throw new NotFoundError(slonikQuery);
}

if (rows.length > 1) {
log.error({
queryId,
}, 'DataIntegrityError');

throw new DataIntegrityError();
throw new DataIntegrityError(slonikQuery);
}

return rows[0];
28 changes: 24 additions & 4 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,10 @@ import {
type ZodIssue,
} from 'zod';
import {
type PrimitiveValueExpression,

type SerializableValue,
type Query,
} from './types';

export class SlonikError extends ExtendableError {}
@@ -53,28 +56,45 @@ export class TupleMovedToAnotherPartitionError extends WrappedPGError {
}

export class NotFoundError extends SlonikError {
public constructor () {
public sql: string;

public values: readonly PrimitiveValueExpression[];

public constructor (query: Query) {
super('Resource not found.');

this.sql = query.sql;
this.values = query.values;
}
}

export class DataIntegrityError extends SlonikError {
public constructor () {
public sql: string;

public values: readonly PrimitiveValueExpression[];

public constructor (query: Query) {
super('Query returns an unexpected result.');

this.sql = query.sql;
this.values = query.values;
}
}

export class SchemaValidationError extends SlonikError {
public sql: string;

public values: readonly PrimitiveValueExpression[];

public row: SerializableValue;

public issues: ZodIssue[];

public constructor (sql: string, row: SerializableValue, issues: ZodIssue[]) {
public constructor (query: Query, row: SerializableValue, issues: ZodIssue[]) {
super('Query returned rows that do not conform with the schema.');

this.sql = sql;
this.sql = query.sql;
this.values = query.values;
this.row = row;
this.issues = issues;
}
2 changes: 1 addition & 1 deletion src/routines/executeQuery.ts
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@ const createParseInterceptor = (parser: ZodTypeAny): Interceptor => {
}, 'row failed validation');

throw new SchemaValidationError(
actualQuery.sql,
actualQuery,
sanitizeObject(row),
validationResult.error.issues,
);
4 changes: 2 additions & 2 deletions test/dts.ts
Original file line number Diff line number Diff line change
@@ -421,8 +421,8 @@ const createSqlTagTypes = () => {

const errorTypes = () => {
new SlonikError();
new NotFoundError();
new DataIntegrityError();
new NotFoundError(sql`SELECT 1`);
new DataIntegrityError(sql`SELECT 1`);
new InvalidConfigurationError();
new StatementCancelledError(new Error('Foo'));
new StatementTimeoutError(new Error('Foo'));