Skip to content

Commit 8522d4c

Browse files
committed
Fixing handling of filesystem errors
Closes #1239 Errors from the filesystem do not have the properties of UnixError such as stdout. This adds a second type check for the properties found on filesystem errors in both mac and linux. Signed-off-by: Matt Farina <matt.farina@suse.com>
1 parent 05c7cb1 commit 8522d4c

7 files changed

Lines changed: 39 additions & 26 deletions

File tree

src/k8s-engine/k3sHelper.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import * as K8s from '@/k8s-engine/k8s';
2323
// TODO: Replace with the k8s version after kubernetes-client/javascript/pull/748 lands
2424
// const k8s = require('@kubernetes/client-node');
2525
import { findHomeDir } from '@/config/findHomeDir';
26-
import { isUnixError } from '@/typings/unix.interface';
26+
import { isUnixError, isUnixFsError } from '@/typings/unix.interface';
2727

2828
const console = Logging.k8s;
2929

@@ -103,7 +103,7 @@ export default class K3sHelper extends events.EventEmitter {
103103
}
104104
}
105105
} catch (ex) {
106-
if (isUnixError(ex) && ex.code !== 'ENOENT') {
106+
if (isUnixFsError(ex) && ex.code !== 'ENOENT') {
107107
throw ex;
108108
}
109109
}
@@ -382,7 +382,7 @@ export default class K3sHelper extends events.EventEmitter {
382382

383383
return (await Promise.all(promises)).filter(x => x)[0];
384384
} catch (ex) {
385-
if (isUnixError(ex) && ex.code !== 'ENOENT') {
385+
if (isUnixFsError(ex) && ex.code !== 'ENOENT') {
386386
throw ex;
387387
}
388388

@@ -536,7 +536,7 @@ export default class K3sHelper extends events.EventEmitter {
536536
return kubeConfigPath;
537537
}
538538
} catch (err) {
539-
if (isUnixError(err) && err.code !== 'ENOENT') {
539+
if (isUnixFsError(err) && err.code !== 'ENOENT') {
540540
throw err;
541541
}
542542
}
@@ -617,7 +617,7 @@ export default class K3sHelper extends events.EventEmitter {
617617
try {
618618
userConfig.loadFromFile(userPath, { onInvalidEntry: ActionOnInvalid.FILTER });
619619
} catch (err) {
620-
if (isUnixError(err) && err.code !== 'ENOENT') {
620+
if (isUnixFsError(err) && err.code !== 'ENOENT') {
621621
console.log(`Error trying to load kubernetes config file ${ userPath }:`, err);
622622
}
623623
// continue to merge into an empty userConfig == `{ contexts: [], clusters: [], users: [] }`

src/k8s-engine/lima.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import SERVICE_BUILDKITD_INIT from '@/assets/scripts/buildkit.initd';
3535
import SERVICE_BUILDKITD_CONF from '@/assets/scripts/buildkit.confd';
3636
import mainEvents from '@/main/mainEvents';
3737
import UnixlikeIntegrations from '@/k8s-engine/unixlikeIntegrations';
38-
import { isUnixError } from '@/typings/unix.interface';
3938
import { getImageProcessor } from '@/k8s-engine/images/imageFactory';
4039

4140
/**
@@ -578,7 +577,7 @@ export default class LimaBackend extends events.EventEmitter implements K8s.Kube
578577

579578
return yaml.parse(configRaw) as LimaConfiguration;
580579
} catch (ex) {
581-
if (isUnixError(ex) && ex.code === 'ENOENT') {
580+
if ((ex as NodeJS.ErrnoException).code === 'ENOENT') {
582581
return undefined;
583582
}
584583
}
@@ -881,7 +880,7 @@ ${ commands.join('\n') }
881880
}
882881
} catch (err) {
883882
dirInfo = null;
884-
if (isUnixError(err) && err.code !== 'ENOENT') {
883+
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
885884
console.log(`Unexpected situation with ${ RUN_LIMA_LOCATION }, stat => error ${ err }`, err);
886885
throw err;
887886
}
@@ -922,7 +921,7 @@ ${ commands.join('\n') }
922921
path = await fs.promises.readlink(path);
923922
}
924923
} catch (err) {
925-
if (isUnixError(err) && err.code !== 'ENOENT') {
924+
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
926925
console.log(`Error trying to resolve symbolic link ${ path }:`, err);
927926
}
928927
}
@@ -973,7 +972,7 @@ ${ commands.join('\n') }
973972
config = NETWORKS_CONFIG;
974973
}
975974
} catch (err) {
976-
if (isUnixError(err) && err.code !== 'ENOENT') {
975+
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
977976
console.log(`Existing networks.yaml file ${ networkPath } not yaml-parsable, got error ${ err }. It will be replaced.`);
978977
}
979978
config = NETWORKS_CONFIG;

src/k8s-engine/unixlikeIntegrations.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import paths from '@/utils/paths';
66
import resources from '@/resources';
77
import PathConflictManager from '@/main/pathConflictManager';
88
import * as window from '@/window';
9-
import { isUnixError } from '@/typings/unix.interface';
9+
import { isUnixFsError } from '@/typings/unix.interface';
1010

1111
const INTEGRATIONS = ['docker', 'helm', 'kubectl', 'nerdctl'];
1212
const console = Logging.background;
@@ -49,9 +49,9 @@ export default class UnixlikeIntegrations {
4949
this.#results[linkPath] = `Already linked to ${ currentDest }`;
5050
}
5151
} catch (error) {
52-
if (isUnixError(error) && error.code === 'ENOENT') {
52+
if (isUnixFsError(error) && error.code === 'ENOENT') {
5353
this.#results[linkPath] = false;
54-
} else if (isUnixError(error) && error.code === 'EINVAL') {
54+
} else if (isUnixFsError(error) && error.code === 'EINVAL') {
5555
this.#results[linkPath] = `File exists and is not a symbolic link`;
5656
} else {
5757
this.#results[linkPath] = `Can't link to ${ linkPath }: ${ error }`;
@@ -73,7 +73,7 @@ export default class UnixlikeIntegrations {
7373
const message = `Error creating symlink for ${ linkPath }:`;
7474

7575
console.error(message, err);
76-
if (isUnixError(err)) {
76+
if (isUnixFsError(err)) {
7777
this.#results[linkPath] = `${ message } ${ err.message }`;
7878
}
7979

@@ -86,7 +86,7 @@ export default class UnixlikeIntegrations {
8686
const message = `Error unlinking symlink for ${ linkPath }`;
8787

8888
console.error(message, err);
89-
if (isUnixError(err)) {
89+
if (isUnixFsError(err)) {
9090
this.#results[linkPath] = `${ message } ${ err.message }`;
9191
}
9292

@@ -113,7 +113,7 @@ export default class UnixlikeIntegrations {
113113
});
114114
}
115115
} catch (error) {
116-
if (!(isUnixError(error))) {
116+
if (!(isUnixFsError(error))) {
117117
return;
118118
}
119119
switch (error.code) {

src/main/pathConflictManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as window from '@/window';
66
import pathConflict from '@/utils/pathConflict';
77
import Logging from '@/utils/logging';
88
import paths from '@/utils/paths';
9-
import { isUnixError } from '@/typings/unix.interface';
9+
import { isUnixFsError } from '@/typings/unix.interface';
1010

1111
const console = Logging.background;
1212
const DebounceInterval = 500; // msec
@@ -69,7 +69,7 @@ export default class PathConflictManager {
6969
try {
7070
await fs.promises.access(dirName, fs.constants.R_OK);
7171
} catch (err) {
72-
if (isUnixError(err) && err.code !== 'ENOENT') {
72+
if (isUnixFsError(err) && err.code !== 'ENOENT') {
7373
console.log(`error in setupPathWatchersForShadowing:`, err);
7474
}
7575
continue;

src/main/paths.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Electron from 'electron';
1212

1313
import Logging from '@/utils/logging';
1414
import paths, { Paths } from '@/utils/paths';
15-
import { isUnixError } from '@/typings/unix.interface';
15+
import { isUnixFsError } from '@/typings/unix.interface';
1616

1717
const console = Logging.background;
1818
const APP_NAME = 'rancher-desktop';
@@ -114,7 +114,7 @@ function removeEmptyParents(directory: string) {
114114
try {
115115
fs.rmdirSync(parent);
116116
} catch (ex) {
117-
if (isUnixError(ex) && expectedErrors.includes(ex.code)) {
117+
if (isUnixFsError(ex) && expectedErrors.includes(ex.code)) {
118118
break;
119119
}
120120
throw ex;
@@ -132,7 +132,7 @@ function recursiveRemoveSync(target: string) {
132132
try {
133133
fs.rmSync(target, { recursive: true });
134134
} catch (ex) {
135-
if (isUnixError(ex) && ex.code === 'ENOENT') {
135+
if (isUnixFsError(ex) && ex.code === 'ENOENT') {
136136
return;
137137
}
138138
throw ex;
@@ -167,7 +167,7 @@ function tryRename(oldPath: string, newPath: string, info: string, deleteOnFailu
167167

168168
return 'succeeded';
169169
} catch (ex) {
170-
if (isUnixError(ex) && ['ENOENT', 'EEXIST'].includes(ex.code)) {
170+
if (isUnixFsError(ex) && ['ENOENT', 'EEXIST'].includes(ex.code)) {
171171
console.error(`Expected error moving ${ info }: ${ ex }`);
172172

173173
return 'failed';

src/main/update/LonghornProvider.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import semver from 'semver';
1212

1313
import Logging from '@/utils/logging';
1414
import paths from '@/utils/paths';
15-
import { isUnixError } from '@/typings/unix.interface';
15+
import { isUnixFsError } from '@/typings/unix.interface';
1616

1717
const console = Logging.update;
1818
const gCachePath = path.join(paths.cache, 'updater-longhorn.json');
@@ -147,7 +147,7 @@ export async function hasQueuedUpdate(): Promise<boolean> {
147147

148148
return true;
149149
} catch (error) {
150-
if (isUnixError(error) && error.code !== 'ENOENT') {
150+
if (isUnixFsError(error) && error.code !== 'ENOENT') {
151151
console.error('Could not check for queued update:', error);
152152
}
153153
}
@@ -164,7 +164,7 @@ export async function setHasQueuedUpdate(isQueued: boolean): Promise<void> {
164164
await fs.promises.writeFile(gCachePath, JSON.stringify(cache),
165165
{ encoding: 'utf-8', mode: 0o600 });
166166
} catch (error) {
167-
if (isUnixError(error) && error.code !== 'ENOENT') {
167+
if (isUnixFsError(error) && error.code !== 'ENOENT') {
168168
console.error('Could not check for queued update:', error);
169169
}
170170
}
@@ -218,7 +218,7 @@ export default class LonghornProvider extends Provider<UpdateInfo> {
218218
return cache;
219219
}
220220
} catch (error) {
221-
if (isUnixError(error) && error.code !== 'ENOENT') {
221+
if (isUnixFsError(error) && error.code !== 'ENOENT') {
222222
// Log the unexpected error, but keep going.
223223
console.error('Error reading update cache:', error);
224224
}

src/typings/unix.interface.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,17 @@ export const isUnixError = (val: any): val is UnixError => {
1111
'code' in val &&
1212
'message' in val;
1313
};
14+
15+
export interface UnixFsError {
16+
syscall: string;
17+
path: string;
18+
code: string;
19+
message: string;
20+
}
21+
22+
export const isUnixFsError = (val: any): val is UnixError => {
23+
return 'syscall' in val &&
24+
'path' in val &&
25+
'code' in val &&
26+
'message' in val;
27+
};

0 commit comments

Comments
 (0)