1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Server: Remove unique constraint errors from the log when they are already handled by the application

This commit is contained in:
Laurent Cozic 2021-11-28 17:26:36 +00:00
parent 7eb1d89d66
commit a6884a2ee4
4 changed files with 23 additions and 7 deletions

View File

@ -47,6 +47,10 @@ export interface DbConfigConnection {
password?: string;
}
export interface QueryContext {
uniqueConstraintErrorLoggingDisabled?: boolean;
}
export interface KnexDatabaseConfig {
client: string;
connection: DbConfigConnection;
@ -204,6 +208,7 @@ interface KnexQueryErrorResponse {
interface KnexQueryErrorData {
bindings: any[];
queryContext: QueryContext;
}
export async function connectDb(dbConfig: DatabaseConfig): Promise<DbConnection> {
@ -214,6 +219,16 @@ export async function connectDb(dbConfig: DatabaseConfig): Promise<DbConnection>
}
connection.on('query-error', (response: KnexQueryErrorResponse, data: KnexQueryErrorData) => {
// It is possible to set certain properties on the query context to
// disable this handler. This is useful for example for constraint
// errors which are often already handled application side.
if (data.queryContext) {
if (data.queryContext.uniqueConstraintErrorLoggingDisabled && isUniqueConstraintError(response)) {
return;
}
}
const msg: string[] = [];
msg.push(response.message);
if (data.bindings && data.bindings.length) msg.push(JSON.stringify(filterBindings(data.bindings), null, ' '));

View File

@ -1,5 +1,5 @@
import { WithDates, WithUuid, databaseSchema, ItemType, Uuid, User } from '../services/database/types';
import { DbConnection } from '../db';
import { DbConnection, QueryContext } from '../db';
import TransactionHandler from '../utils/TransactionHandler';
import uuidgen from '../utils/uuidgen';
import { ErrorUnprocessableEntity, ErrorBadRequest } from '../utils/errors';
@ -24,6 +24,7 @@ export interface SaveOptions {
skipValidation?: boolean;
validationRules?: any;
previousItem?: any;
queryContext?: QueryContext;
}
export interface LoadOptions {
@ -297,12 +298,12 @@ export default abstract class BaseModel<T> {
await this.withTransaction(async () => {
if (isNew) {
await this.db(this.tableName).insert(toSave);
await this.db(this.tableName).insert(toSave).queryContext(options.queryContext || {});
} else {
const objectId: string = (toSave as WithUuid).id;
if (!objectId) throw new Error('Missing "id" property');
delete (toSave as WithUuid).id;
const updatedCount: number = await this.db(this.tableName).update(toSave).where({ id: objectId });
const updatedCount: number = await this.db(this.tableName).update(toSave).where({ id: objectId }).queryContext(options.queryContext || {});
(toSave as WithUuid).id = objectId;
// Sanity check:

View File

@ -179,7 +179,7 @@ export default class ShareModel extends BaseModel<Share> {
const addUserItem = async (shareUserId: Uuid, itemId: Uuid) => {
try {
await this.models().userItem().add(shareUserId, itemId);
await this.models().userItem().add(shareUserId, itemId, { queryContext: { uniqueConstraintErrorLoggingDisabled: true } });
} catch (error) {
if (!isUniqueConstraintError(error)) throw error;
}
@ -322,7 +322,7 @@ export default class ShareModel extends BaseModel<Share> {
for (const resourceItem of resourceItems) {
if (doShare) {
try {
await this.models().userItem().add(toUserId, resourceItem.id);
await this.models().userItem().add(toUserId, resourceItem.id, { queryContext: { uniqueConstraintErrorLoggingDisabled: true } });
} catch (error) {
if (isUniqueConstraintError(error)) {
continue;
@ -337,7 +337,7 @@ export default class ShareModel extends BaseModel<Share> {
for (const resourceBlobItem of resourceBlobItems) {
if (doShare) {
try {
await this.models().userItem().add(toUserId, resourceBlobItem.id);
await this.models().userItem().add(toUserId, resourceBlobItem.id, { queryContext: { uniqueConstraintErrorLoggingDisabled: true } });
} catch (error) {
if (isUniqueConstraintError(error)) {
continue;

View File

@ -37,7 +37,7 @@ export default class UserFlagModels extends BaseModel<UserFlag> {
await this.save({
user_id: userId,
type,
});
}, { queryContext: { uniqueConstraintErrorLoggingDisabled: true } });
} catch (error) {
if (!isUniqueConstraintError(error)) {
throw error;