Skip to content

Commit

Permalink
fix: Prevent exception if toggling in unsaved file in Reading mode (#…
Browse files Browse the repository at this point in the history
…1772)

* fix: Prevent exception if toggling in unsaved file in Reading mode

See the comment #1680 (comment)
in #1680.

If lines had been deleted from a file, and it was not yet saved when user
then toggled a line near the end of the file in Reading mode,
there could be an access of a non-existent line number.

The resultant output was:

plugin:obsidian-tasks-plugin:17605 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'includes')
    at eval (plugin:obsidian-tasks-plugin:17605:14)
    at Generator.next (<anonymous>)
    at fulfilled (plugin:obsidian-tasks-plugin:173:24)

* comment: Fix typo
  • Loading branch information
claremacrae committed Mar 20, 2023
1 parent 4ad363b commit 6332135
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 4 deletions.
15 changes: 12 additions & 3 deletions src/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,23 +192,32 @@ export function findLineNumberOfTaskToToggle(
listItemsCache: ListItemCache[] | MockListItemCache[],
errorLoggingFunction: ErrorLoggingFunction,
) {
const fileLinesCount = fileLines.length;
const { globalFilter } = getSettings();
let taskLineNumber: number | undefined;
let sectionIndex = 0;
for (const listItemCache of listItemsCache) {
if (listItemCache.position.start.line < originalTask.taskLocation.sectionStart) {
const listItemLineNumber = listItemCache.position.start.line;
if (listItemLineNumber >= fileLinesCount) {
// One or more lines has been deleted since the cache was populated,
// so there is at least one list item in the cache that is beyond
// the end of the actual file on disk.
return undefined;
}

if (listItemLineNumber < originalTask.taskLocation.sectionStart) {
continue;
}

if (listItemCache.task === undefined) {
continue;
}

const line = fileLines[listItemCache.position.start.line];
const line = fileLines[listItemLineNumber];
if (line.includes(globalFilter)) {
if (sectionIndex === originalTask.taskLocation.sectionIndex) {
if (line === originalTask.originalMarkdown) {
taskLineNumber = listItemCache.position.start.line;
taskLineNumber = listItemLineNumber;
} else {
errorLoggingFunction(
`Tasks: Unable to find task in file ${originalTask.taskLocation.path}.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Could not find line for task
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Could not find line for task
30 changes: 29 additions & 1 deletion tests/File.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ function testFindLineNumberOfTaskToToggle(
);

// Assert
verify(errorString ? errorString : 'Success. Line found OK. No error reported.');
let descriptionOfOutcome = '';
if (errorString !== undefined) {
descriptionOfOutcome = errorString;
} else if (result === undefined) {
descriptionOfOutcome = 'Could not find line for task';
} else {
descriptionOfOutcome = 'Success. Line found OK. No error reported.';
}
verify(descriptionOfOutcome);

if (expectedLineNumber !== undefined) {
expect(result).not.toBeUndefined();
Expand Down Expand Up @@ -97,5 +105,25 @@ describe('replaceTaskWithTasks', () => {
});
});

// --------------------------------------------------------------------------------
// Issue 1680
describe('issue 1680 - Cannot read properties of undefined', () => {
const jsonFileName = '1680_task_line_number_past_end_of_file.json';
const taskLineToToggle = '- [ ] #task Section 2/Task 2';

it.failing('correct behaviour', () => {
// An incorrect line is currently found, so this test fails, due to bug 1680
const expectedLineNumber = 9;
testFindLineNumberOfTaskToToggle(jsonFileName, taskLineToToggle, expectedLineNumber);
});

it('current incorrect behaviour', () => {
// An incorrect line is currently found, due to bug 688.
// It is recognised as an incorrect line, and so line number is returned as undefined.
const expectedLineNumber = undefined;
testFindLineNumberOfTaskToToggle(jsonFileName, taskLineToToggle, expectedLineNumber);
});
});

// --------------------------------------------------------------------------------
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"taskData": {
"originalMarkdown": "- [ ] #task Section 2/Task 2",
"taskLocation": {
"path": "Manual Testing/Task Toggling Scenarios/1680 - Reading Mode line numbers not updated on editing.md",
"lineNumber": 14,
"sectionStart": 13,
"sectionIndex": 1,
"precedingHeader": null
}
},
"fileData": {
"fileLines": [
"## Test Data",
"",
"### Tasks Section 1",
"- [ ] #task Section 1/Task 1",
"- [ ] #task Section 1/Task 2",
"",
"### Tasks Section 2",
"",
"- [ ] #task Section 2/Task 1",
"- [ ] #task Section 2/Task 2",
""
]
},
"cacheData": {
"listItemsCache": [
{
"position": {
"start": {
"line": 8,
"col": 0,
"offset": 39
},
"end": {
"line": 8,
"col": 28,
"offset": 67
}
},
"task": " "
},
{
"position": {
"start": {
"line": 9,
"col": 0,
"offset": 68
},
"end": {
"line": 9,
"col": 28,
"offset": 96
}
},
"task": " "
},
{
"position": {
"start": {
"line": 13,
"col": 0,
"offset": 119
},
"end": {
"line": 13,
"col": 28,
"offset": 147
}
},
"task": " "
},
{
"position": {
"start": {
"line": 14,
"col": 0,
"offset": 148
},
"end": {
"line": 14,
"col": 28,
"offset": 176
}
},
"task": " "
}
]
}
}

0 comments on commit 6332135

Please sign in to comment.