From 8edf06d28ddc948384ebe680b0b508a6ead24b65 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 4 May 2023 22:16:18 +0200 Subject: [PATCH] small refactorings --- src/becca/entities/battribute.js | 2 +- src/becca/entities/bnote.js | 8 +++++--- src/becca/entity_constructor.js | 2 +- src/etapi/auth.js | 2 +- src/public/app/entities/fnote.js | 8 +++++--- src/public/app/widgets/containers/flex_container.js | 2 +- src/public/app/widgets/dialogs/export.js | 2 +- .../app/widgets/mobile_widgets/mobile_detail_menu.js | 2 +- src/public/app/widgets/note_detail.js | 2 +- src/public/app/widgets/note_tree.js | 4 ++-- .../app/widgets/ribbon_widgets/book_properties.js | 2 +- src/public/app/widgets/type_widgets/attachment_list.js | 2 +- src/public/app/widgets/type_widgets/image.js | 2 +- src/routes/api/branches.js | 2 +- src/routes/api/options.js | 2 +- src/services/cloning.js | 2 +- src/services/date_utils.js | 2 +- src/services/entity_changes.js | 2 +- src/services/etapi_tokens.js | 2 +- src/services/events.js | 2 +- src/services/handlers.js | 7 ++----- src/services/hoisted_note.js | 2 +- src/services/notes.js | 10 +++++++--- src/services/options.js | 6 +++--- src/services/request.js | 2 +- src/services/sync.js | 6 +++--- src/services/tree.js | 4 ++-- src/share/shaca/entities/sattribute.js | 2 +- 28 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/becca/entities/battribute.js b/src/becca/entities/battribute.js index 61213061a..e57691e94 100644 --- a/src/becca/entities/battribute.js +++ b/src/becca/entities/battribute.js @@ -141,7 +141,7 @@ class BAttribute extends AbstractBeccaEntity { */ getTargetNote() { if (this.type !== 'relation') { - throw new Error(`Attribute ${this.attributeId} is not relation`); + throw new Error(`Attribute '${this.attributeId}' is not a relation.`); } if (!this.value) { diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js index ac56bceb2..c20db6f1c 100644 --- a/src/becca/entities/bnote.js +++ b/src/becca/entities/bnote.js @@ -1445,14 +1445,16 @@ class BNote extends AbstractBeccaEntity { const targetRelations = this.getTargetRelations().filter(relation => relation.name === 'imageLink'); - if (targetRelations.length !== 1) { + if (targetRelations.length > 1) { return false; } const parentNote = this.getParentNotes()[0]; // at this point note can have only one parent - const referencingNote = targetRelations[0].getNote(); + const referencingNote = targetRelations[0]?.getNote(); - if (parentNote !== referencingNote || parentNote.type !== 'text' || !parentNote.isContentAvailable()) { + if (referencingNote && parentNote !== referencingNote) { + return false; + } else if (parentNote.type !== 'text' || !parentNote.isContentAvailable()) { return false; } diff --git a/src/becca/entity_constructor.js b/src/becca/entity_constructor.js index bd4e125bf..d04702e6a 100644 --- a/src/becca/entity_constructor.js +++ b/src/becca/entity_constructor.js @@ -20,7 +20,7 @@ const ENTITY_NAME_TO_ENTITY = { function getEntityFromEntityName(entityName) { if (!(entityName in ENTITY_NAME_TO_ENTITY)) { - throw new Error(`Entity for table ${entityName} not found!`); + throw new Error(`Entity for table '${entityName}' not found!`); } return ENTITY_NAME_TO_ENTITY[entityName]; diff --git a/src/etapi/auth.js b/src/etapi/auth.js index 921c91d94..8190c1bd2 100644 --- a/src/etapi/auth.js +++ b/src/etapi/auth.js @@ -29,7 +29,7 @@ function register(router, loginMiddleware) { if (!etapiToken) { // shouldn't happen since this already passed auth validation - throw new Error(`Cannot find the token ${parsed.etapiTokenId}.`); + throw new Error(`Cannot find the token '${parsed.etapiTokenId}'.`); } etapiToken.markAsDeletedSimple(); diff --git a/src/public/app/entities/fnote.js b/src/public/app/entities/fnote.js index cfe53cd84..9f942cd95 100644 --- a/src/public/app/entities/fnote.js +++ b/src/public/app/entities/fnote.js @@ -252,14 +252,16 @@ class FNote { const targetRelations = this.getTargetRelations().filter(relation => relation.name === 'imageLink'); - if (targetRelations.length !== 1) { + if (targetRelations.length > 1) { return false; } const parentNote = this.getParentNotes()[0]; // at this point note can have only one parent - const referencingNote = targetRelations[0].getNote(); + const referencingNote = targetRelations[0]?.getNote(); - if (parentNote !== referencingNote || parentNote.type !== 'text' || !parentNote.isContentAvailable()) { + if (referencingNote && referencingNote !== parentNote) { + return false; + } else if (parentNote.type !== 'text' || !parentNote.isContentAvailable()) { return false; } diff --git a/src/public/app/widgets/containers/flex_container.js b/src/public/app/widgets/containers/flex_container.js index 7ece8aff0..ae3ffb107 100644 --- a/src/public/app/widgets/containers/flex_container.js +++ b/src/public/app/widgets/containers/flex_container.js @@ -5,7 +5,7 @@ export default class FlexContainer extends Container { super(); if (!direction || !['row', 'column'].includes(direction)) { - throw new Error(`Direction argument given as "${direction}", use either 'row' or 'column'`); + throw new Error(`Direction argument given as '${direction}', use either 'row' or 'column'`); } this.attrs.style = `display: flex; flex-direction: ${direction};`; diff --git a/src/public/app/widgets/dialogs/export.js b/src/public/app/widgets/dialogs/export.js index 9fcb098ba..9e23d11d0 100644 --- a/src/public/app/widgets/dialogs/export.js +++ b/src/public/app/widgets/dialogs/export.js @@ -203,7 +203,7 @@ export default class ExportDialog extends BasicWidget { this.$singleType.prop("checked", true).trigger('change'); } else { - throw new Error(`Unrecognized type ${defaultType}`); + throw new Error(`Unrecognized type '${defaultType}'`); } this.$widget.find(".opml-v2").prop("checked", true); // setting default diff --git a/src/public/app/widgets/mobile_widgets/mobile_detail_menu.js b/src/public/app/widgets/mobile_widgets/mobile_detail_menu.js index 84430c7d1..56b237398 100644 --- a/src/public/app/widgets/mobile_widgets/mobile_detail_menu.js +++ b/src/public/app/widgets/mobile_widgets/mobile_detail_menu.js @@ -32,7 +32,7 @@ class MobileDetailMenuWidget extends BasicWidget { const branchId = await treeService.getBranchIdFromNotePath(notePath); if (!branchId) { - throw new Error(`Cannot get branchId for notePath ${notePath}`); + throw new Error(`Cannot get branchId for notePath '${notePath}'`); } if (await branchService.deleteNotes([branchId])) { diff --git a/src/public/app/widgets/note_detail.js b/src/public/app/widgets/note_detail.js index 6b6302c85..0784224fc 100644 --- a/src/public/app/widgets/note_detail.js +++ b/src/public/app/widgets/note_detail.js @@ -174,7 +174,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget { getTypeWidget() { if (!this.typeWidgets[this.type]) { - throw new Error(`Could not find typeWidget for type: ${this.type}`); + throw new Error(`Could not find typeWidget for type '${this.type}'`); } return this.typeWidgets[this.type]; diff --git a/src/public/app/widgets/note_tree.js b/src/public/app/widgets/note_tree.js index 1bf03d2ce..8221fd448 100644 --- a/src/public/app/widgets/note_tree.js +++ b/src/public/app/widgets/note_tree.js @@ -475,7 +475,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { } else if (data.hitMode === "over") { branchService.moveToParentNote(selectedBranchIds, node.data.branchId); } else { - throw new Error(`Unknown hitMode=${data.hitMode}`); + throw new Error(`Unknown hitMode '${data.hitMode}'`); } } } @@ -691,7 +691,7 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { const note = branch.getNoteFromCache(); if (!note) { - throw new Error(`Branch "${branch.branchId}" has no child note "${branch.noteId}"`); + throw new Error(`Branch '${branch.branchId}' has no child note '${branch.noteId}'`); } const title = `${branch.prefix ? (`${branch.prefix} - `) : ""}${note.title}`; diff --git a/src/public/app/widgets/ribbon_widgets/book_properties.js b/src/public/app/widgets/ribbon_widgets/book_properties.js index 7aff9a5aa..3bc1e51fc 100644 --- a/src/public/app/widgets/ribbon_widgets/book_properties.js +++ b/src/public/app/widgets/ribbon_widgets/book_properties.js @@ -101,7 +101,7 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget { async toggleViewType(type) { if (type !== 'list' && type !== 'grid') { - throw new Error(`Invalid view type ${type}`); + throw new Error(`Invalid view type '${type}'`); } await attributeService.setLabel(this.noteId, 'viewType', type); diff --git a/src/public/app/widgets/type_widgets/attachment_list.js b/src/public/app/widgets/type_widgets/attachment_list.js index 0072a14be..e4876e995 100644 --- a/src/public/app/widgets/type_widgets/attachment_list.js +++ b/src/public/app/widgets/type_widgets/attachment_list.js @@ -33,7 +33,7 @@ export default class AttachmentListTypeWidget extends TypeWidget { const attachments = await server.get(`notes/${this.noteId}/attachments?includeContent=true`); if (attachments.length === 0) { - this.$list.html("This note has no attachments."); + this.$list.html('
This note has no attachments.
'); return; } diff --git a/src/public/app/widgets/type_widgets/image.js b/src/public/app/widgets/type_widgets/image.js index d35f9b634..53c8e3ba1 100644 --- a/src/public/app/widgets/type_widgets/image.js +++ b/src/public/app/widgets/type_widgets/image.js @@ -79,7 +79,7 @@ class ImageTypeWidget extends TypeWidget { utils.dynamicRequire('electron'); webContents.copyImageAt(e.pageX, e.pageY); } else { - throw new Error(`Unrecognized command ${command}`); + throw new Error(`Unrecognized command '${command}'`); } } }); diff --git a/src/routes/api/branches.js b/src/routes/api/branches.js index 5bc8a3c70..0c1f1f34e 100644 --- a/src/routes/api/branches.js +++ b/src/routes/api/branches.js @@ -24,7 +24,7 @@ function moveBranchToParent(req) { const branchToMove = becca.getBranch(branchId); if (!parentBranch || !branchToMove) { - throw new ValidationError(`One or both branches ${branchId}, ${parentBranchId} have not been found`); + throw new ValidationError(`One or both branches '${branchId}', '${parentBranchId}' have not been found`); } return branchService.moveBranchToBranch(branchToMove, parentBranch, branchId); diff --git a/src/routes/api/options.js b/src/routes/api/options.js index 900ea49d4..89a02d726 100644 --- a/src/routes/api/options.js +++ b/src/routes/api/options.js @@ -93,7 +93,7 @@ function updateOptions(req) { if (!update(optionName, req.body[optionName])) { // this should be improved // it should return 400 instead of current 500, but at least it now rollbacks transaction - throw new Error(`${optionName} is not allowed to change`); + throw new Error(`Option '${optionName}' is not allowed to be changed`); } } } diff --git a/src/services/cloning.js b/src/services/cloning.js index 30235fbc1..eaa7682da 100644 --- a/src/services/cloning.js +++ b/src/services/cloning.js @@ -48,7 +48,7 @@ function cloneNoteToBranch(noteId, parentBranchId, prefix) { const parentBranch = becca.getBranch(parentBranchId); if (!parentBranch) { - return { success: false, message: `Parent branch ${parentBranchId} does not exist.` }; + return { success: false, message: `Parent branch '${parentBranchId}' does not exist.` }; } const ret = cloneNoteToParentNote(noteId, parentBranch.noteId, prefix); diff --git a/src/services/date_utils.js b/src/services/date_utils.js index 5c9a4a835..6c39ac1b1 100644 --- a/src/services/date_utils.js +++ b/src/services/date_utils.js @@ -47,7 +47,7 @@ function parseDateTime(str) { return new Date(Date.parse(str)); } catch (e) { - throw new Error(`Can't parse date from ${str}: ${e.stack}`); + throw new Error(`Can't parse date from '${str}': ${e.stack}`); } } diff --git a/src/services/entity_changes.js b/src/services/entity_changes.js index 51fad2520..4b58fad46 100644 --- a/src/services/entity_changes.js +++ b/src/services/entity_changes.js @@ -137,7 +137,7 @@ function fillEntityChanges(entityName, entityPrimaryKey, condition = '') { } if (createdCount > 0) { - log.info(`Created ${createdCount} missing entity changes for ${entityName}.`); + log.info(`Created ${createdCount} missing entity changes for entity '${entityName}'.`); } }); } diff --git a/src/services/etapi_tokens.js b/src/services/etapi_tokens.js index bdb65800b..23e71e4f0 100644 --- a/src/services/etapi_tokens.js +++ b/src/services/etapi_tokens.js @@ -97,7 +97,7 @@ function renameToken(etapiTokenId, newName) { const etapiToken = becca.getEtapiToken(etapiTokenId); if (!etapiToken) { - throw new Error(`Token ${etapiTokenId} does not exist`); + throw new Error(`Token '${etapiTokenId}' does not exist`); } etapiToken.name = newName; diff --git a/src/services/events.js b/src/services/events.js index f188ffe71..91dda3e23 100644 --- a/src/services/events.js +++ b/src/services/events.js @@ -49,7 +49,7 @@ function emit(eventType, data) { listener(data); } catch (e) { - log.error(`Listener threw error: ${e.stack}`); + log.error(`Listener threw error: ${e.message}, stack: ${e.stack}`); // we won't stop execution because of listener } } diff --git a/src/services/handlers.js b/src/services/handlers.js index b1ccfa63f..1cdaa2cb7 100644 --- a/src/services/handlers.js +++ b/src/services/handlers.js @@ -218,11 +218,8 @@ eventService.subscribe(eventService.ENTITY_DELETED, ({ entityName, entity }) => if (entityName === 'notes' && entity.noteId.startsWith("_")) { // "named" note has been deleted, we will probably need to rebuild the hidden subtree // scheduling so that bulk deletes won't trigger so many checks - oneTimeTimer.scheduleExecution('hidden-subtree-check', 1000, () => { - console.log("Checking hidden subtree"); - - hiddenSubtreeService.checkHiddenSubtree(); - }); + oneTimeTimer.scheduleExecution('hidden-subtree-check', 1000, + () => hiddenSubtreeService.checkHiddenSubtree()); } }); diff --git a/src/services/hoisted_note.js b/src/services/hoisted_note.js index ea12a17f5..de64f2da0 100644 --- a/src/services/hoisted_note.js +++ b/src/services/hoisted_note.js @@ -17,7 +17,7 @@ function isHoistedInHiddenSubtree() { const hoistedNote = becca.getNote(hoistedNoteId); if (!hoistedNote) { - throw new Error(`Cannot find hoisted note ${hoistedNoteId}`); + throw new Error(`Cannot find hoisted note '${hoistedNoteId}'`); } return hoistedNote.isHiddenCompletely(); diff --git a/src/services/notes.js b/src/services/notes.js index aea15551d..d0902161a 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -116,7 +116,7 @@ function getAndValidateParent(params) { const parentNote = becca.notes[params.parentNoteId]; if (!parentNote) { - throw new ValidationError(`Parent note "${params.parentNoteId}" not found.`); + throw new ValidationError(`Parent note '${params.parentNoteId}' was not found.`); } if (parentNote.type === 'launcher' && parentNote.noteId !== '_lbBookmarks') { @@ -281,7 +281,7 @@ function createNewNoteWithTarget(target, targetBranchId, params) { return retObject; } else { - throw new Error(`Unknown target ${target}`); + throw new Error(`Unknown target '${target}'`); } } @@ -883,11 +883,15 @@ function eraseUnusedBlobs() { FROM blobs LEFT JOIN notes ON notes.blobId = blobs.blobId LEFT JOIN attachments ON attachments.blobId = blobs.blobId - LEFT JOIN note_revisions ON attachments.blobId = blobs.blobId + LEFT JOIN note_revisions ON note_revisions.blobId = blobs.blobId WHERE notes.noteId IS NULL AND attachments.attachmentId IS NULL AND note_revisions.noteRevisionId IS NULL`); + if (unusedBlobIds.length === 0) { + return; + } + sql.executeMany(`DELETE FROM blobs WHERE blobId IN (???)`, unusedBlobIds); setEntityChangesAsErased(sql.getManyRows(`SELECT * FROM entity_changes WHERE entityName = 'blobs' AND entityId IN (???)`, unusedBlobIds)); diff --git a/src/services/options.js b/src/services/options.js index 9d227ec4c..62d4c5aa2 100644 --- a/src/services/options.js +++ b/src/services/options.js @@ -10,7 +10,7 @@ function getOptionOrNull(name) { // e.g. in initial sync becca is not loaded because DB is not initialized option = sql.getRow("SELECT * FROM options WHERE name = ?", name); } - + return option ? option.value : null; } @@ -33,7 +33,7 @@ function getOptionInt(name) { const intVal = parseInt(val); if (isNaN(intVal)) { - throw new Error(`Could not parse "${val}" into integer for option "${name}"`); + throw new Error(`Could not parse '${val}' into integer for option '${name}'`); } return intVal; @@ -46,7 +46,7 @@ function getOptionBool(name) { const val = getOption(name); if (!['true', 'false'].includes(val)) { - throw new Error(`Could not parse "${val}" into boolean for option "${name}"`); + throw new Error(`Could not parse '${val}' into boolean for option '${name}'`); } return val === 'true'; diff --git a/src/services/request.js b/src/services/request.js index 78370ad7d..3b42670ad 100644 --- a/src/services/request.js +++ b/src/services/request.js @@ -182,7 +182,7 @@ function getClient(opts) { return require(protocol.substr(0, protocol.length - 1)); } else { - throw new Error(`Unrecognized protocol "${protocol}"`); + throw new Error(`Unrecognized protocol '${protocol}'`); } } } diff --git a/src/services/sync.js b/src/services/sync.js index 77622d6ce..d6b8d004a 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -109,7 +109,7 @@ async function doLogin() { }); if (resp.instanceId === instanceId) { - throw new Error(`Sync server has member ID ${resp.instanceId} which is also local. This usually happens when the sync client is (mis)configured to sync with itself (URL points back to client) instead of the correct sync server.`); + throw new Error(`Sync server has member ID '${resp.instanceId}' which is also local. This usually happens when the sync client is (mis)configured to sync with itself (URL points back to client) instead of the correct sync server.`); } syncContext.instanceId = resp.instanceId; @@ -312,13 +312,13 @@ function getEntityChangeRow(entityName, entityId) { const primaryKey = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; if (!primaryKey) { - throw new Error(`Unknown entity ${entityName}`); + throw new Error(`Unknown entity '${entityName}'`); } const entity = sql.getRow(`SELECT * FROM ${entityName} WHERE ${primaryKey} = ?`, [entityId]); if (!entity) { - throw new Error(`Entity ${entityName} ${entityId} not found.`); + throw new Error(`Entity ${entityName} '${entityId}' not found.`); } if (entityName === 'blobs' && entity.content !== null) { diff --git a/src/services/tree.js b/src/services/tree.js index 5c3798680..5e77a9504 100644 --- a/src/services/tree.js +++ b/src/services/tree.js @@ -200,7 +200,7 @@ function setNoteToParent(noteId, prefix, parentNoteId) { const parentNote = becca.getNote(parentNoteId); if (parentNote && parentNote.isDeleted) { - throw new Error(`Cannot move note to deleted parent note ${parentNoteId}`); + throw new Error(`Cannot move note to deleted parent note '${parentNoteId}'`); } // case where there might be more such branches is ignored. It's expected there should be just one @@ -224,7 +224,7 @@ function setNoteToParent(noteId, prefix, parentNoteId) { const note = becca.getNote(noteId); if (note.isDeleted) { - throw new Error(`Cannot create a branch for ${noteId} which is deleted.`); + throw new Error(`Cannot create a branch for '${noteId}' which is deleted.`); } const branchId = sql.getValue('SELECT branchId FROM branches WHERE isDeleted = 0 AND noteId = ? AND parentNoteId = ?', [noteId, parentNoteId]); diff --git a/src/share/shaca/entities/sattribute.js b/src/share/shaca/entities/sattribute.js index 9e0509aa9..dea4b950e 100644 --- a/src/share/shaca/entities/sattribute.js +++ b/src/share/shaca/entities/sattribute.js @@ -89,7 +89,7 @@ class SAttribute extends AbstractShacaEntity { /** @returns {SNote|null} */ getTargetNote() { if (this.type !== 'relation') { - throw new Error(`Attribute ${this.attributeId} is not relation`); + throw new Error(`Attribute '${this.attributeId}' is not relation`); } if (!this.value) {