Skip to content

Commit

Permalink
feat: Remove fs compatibility wrappers (v5) (#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
timfish authored Apr 8, 2024
1 parent 7bc6ad0 commit 670e920
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 75 deletions.
6 changes: 6 additions & 0 deletions src/main/electron-normalize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { parseSemver } from '@sentry/utils';
import { app } from 'electron';
import { join } from 'path';

import { RENDERER_ID_HEADER } from '../common/ipc';

Expand All @@ -20,6 +21,11 @@ export const EXIT_REASONS = [
export type ExitReason = (typeof EXIT_REASONS)[number];
export const CRASH_REASONS: Readonly<ExitReason[]> = ['crashed', 'oom'] as const;

/** Gets the Sentry Cache path */
export function getSentryCachePath(): string {
return join(app.getPath('userData'), 'sentry');
}

/**
* Uses Crashpad on Linux
* https://github.com/electron/electron/issues/27859
Expand Down
47 changes: 0 additions & 47 deletions src/main/fs.ts

This file was deleted.

3 changes: 1 addition & 2 deletions src/main/integrations/sentry-minidump/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { app, crashReporter } from 'electron';

import { addScopeListener, getScopeData } from '../../../common/scope';
import { getEventDefaults } from '../../context';
import { EXIT_REASONS } from '../../electron-normalize';
import { getSentryCachePath } from '../../fs';
import { EXIT_REASONS, getSentryCachePath } from '../../electron-normalize';
import { getRendererProperties, trackRendererProperties } from '../../renderers';
import { ElectronMainOptions } from '../../sdk';
import { checkPreviousSession, sessionCrashed } from '../../sessions';
Expand Down
18 changes: 9 additions & 9 deletions src/main/integrations/sentry-minidump/minidump-loader.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Attachment } from '@sentry/types';
import { basename, logger } from '@sentry/utils';
import { app } from 'electron';
import { promises as fs } from 'fs';
import { join } from 'path';

import { usesCrashpad } from '../../electron-normalize';
import { readDirAsync, readFileAsync, statAsync, unlinkAsync } from '../../fs';
import { Mutex } from '../../mutex';

/** Maximum number of days to keep a minidump before deleting it. */
Expand Down Expand Up @@ -53,7 +53,7 @@ export function createMinidumpLoader(

logger.log('Found minidump', path);

let stats = await statAsync(path);
let stats = await fs.stat(path);

const thirtyDaysAgo = new Date().getTime() - MAX_AGE_DAYS * MS_PER_DAY;

Expand All @@ -68,7 +68,7 @@ export function createMinidumpLoader(
const twoSecondsAgo = new Date().getTime() - NOT_MODIFIED_MS;

if (stats.mtimeMs < twoSecondsAgo) {
const file = await readFileAsync(path);
const file = await fs.readFile(path);
const data = preProcessFile(file);

if (data.length < 10_000 || data.subarray(0, 4).toString() !== MINIDUMP_HEADER) {
Expand All @@ -91,7 +91,7 @@ export function createMinidumpLoader(
retries += 1;
await delay(RETRY_DELAY_MS);
// update the stats
stats = await statAsync(path);
stats = await fs.stat(path);
}

if (retries >= MAX_RETRIES) {
Expand All @@ -102,7 +102,7 @@ export function createMinidumpLoader(
} finally {
// We always attempt to delete the minidump
try {
await unlinkAsync(path);
await fs.unlink(path);
} catch (e) {
logger.warn('Could not delete minidump', path);
}
Expand All @@ -120,7 +120,7 @@ async function deleteCrashpadMetadataFile(crashesDirectory: string, waitMs: numb

const metadataPath = join(crashesDirectory, 'metadata');
try {
await unlinkAsync(metadataPath);
await fs.unlink(metadataPath);
logger.log('Deleted Crashpad metadata file', metadataPath);
} catch (e: any) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Expand All @@ -138,7 +138,7 @@ async function readDirsAsync(paths: string[]): Promise<string[]> {
const found: string[] = [];
for (const path of paths) {
try {
const files = await readDirAsync(path);
const files = await fs.readdir(path);
found.push(...files.map((file) => join(path, file)));
} catch (_) {
//
Expand Down Expand Up @@ -187,7 +187,7 @@ function removeBreakpadMetadata(crashesDirectory: string, paths: string[]): void
.map(async (file) => {
const path = join(crashesDirectory, file);
try {
await unlinkAsync(path);
await fs.unlink(path);
} catch (e) {
logger.warn('Could not delete', path);
}
Expand All @@ -203,7 +203,7 @@ function breakpadMinidumpLoader(): MinidumpLoader {
return createMinidumpLoader(async () => {
// Breakpad stores all minidump files along with a metadata file directly in
// the crashes directory.
const files = await readDirAsync(crashesDirectory);
const files = await fs.readdir(crashesDirectory);
removeBreakpadMetadata(crashesDirectory, files);
return files.filter((file) => file.endsWith('.dmp')).map((file) => join(crashesDirectory, file));
}, minidumpFromBreakpadMultipart);
Expand Down
2 changes: 1 addition & 1 deletion src/main/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { SerializedSession, Session, SessionContext, SessionStatus } from '@sent
import { logger } from '@sentry/utils';
import { app } from 'electron';

import { getSentryCachePath } from './fs';
import { getSentryCachePath } from './electron-normalize';
import { Store } from './store';

const PERSIST_INTERVAL_MS = 60_000;
Expand Down
12 changes: 6 additions & 6 deletions src/main/store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { logger } from '@sentry/utils';
import { promises as fs } from 'fs';
import { dirname, join } from 'path';

import { mkdirp, readFileAsync, statAsync, unlinkAsync, writeFileAsync } from './fs';
import { Mutex } from './mutex';

const dateFormat = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.*\d{0,10}Z$/;
Expand Down Expand Up @@ -53,13 +53,13 @@ export class Store<T> {
try {
if (data === undefined) {
try {
await unlinkAsync(this._path);
await fs.unlink(this._path);
} catch (_) {
//
}
} else {
await mkdirp(dirname(this._path));
await writeFileAsync(this._path, JSON.stringify(data));
await fs.mkdir(dirname(this._path), { recursive: true });
await fs.writeFile(this._path, JSON.stringify(data));
}
} catch (e) {
logger.warn('Failed to write to store', e);
Expand All @@ -81,7 +81,7 @@ export class Store<T> {
return this._lock.runExclusive(async () => {
if (this._data === undefined) {
try {
this._data = JSON.parse(await readFileAsync(this._path, 'utf8'), dateReviver) as T;
this._data = JSON.parse(await fs.readFile(this._path, 'utf8'), dateReviver) as T;
} catch (e) {
this._data = this._initial;
}
Expand All @@ -107,7 +107,7 @@ export class Store<T> {
/** Gets the Date that the file was last modified */
public async getModifiedDate(): Promise<Date | undefined> {
try {
return (await statAsync(this._path))?.mtime;
return (await fs.stat(this._path))?.mtime;
} catch (_) {
return undefined;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/transports/electron-offline-net.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { logger } from '@sentry/utils';
import { net } from 'electron';
import { join } from 'path';

import { getSentryCachePath } from '../fs';
import { getSentryCachePath } from '../electron-normalize';
import { createElectronNetRequestExecutor, ElectronNetTransportOptions } from './electron-net';
import { PersistedRequestQueue } from './queue';

Expand Down
8 changes: 4 additions & 4 deletions src/main/transports/queue.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { TransportRequest } from '@sentry/types';
import { logger, uuid4 } from '@sentry/utils';
import { promises as fs } from 'fs';
import { join } from 'path';

import { readFileAsync, unlinkAsync, writeFileAsync } from '../fs';
import { BufferedWriteStore } from '../store';

const MILLISECONDS_PER_DAY = 86_400_000;
Expand Down Expand Up @@ -59,7 +59,7 @@ export class PersistedRequestQueue {
});

try {
await writeFileAsync(join(this._queuePath, bodyPath), request.body);
await fs.writeFile(join(this._queuePath, bodyPath), request.body);
} catch (_) {
//
}
Expand Down Expand Up @@ -90,7 +90,7 @@ export class PersistedRequestQueue {

if (found) {
try {
const body = await readFileAsync(join(this._queuePath, found.bodyPath));
const body = await fs.readFile(join(this._queuePath, found.bodyPath));
this._removeBody(found.bodyPath);

return {
Expand All @@ -110,7 +110,7 @@ export class PersistedRequestQueue {

/** Removes the body of the request */
private _removeBody(bodyPath: string): void {
unlinkAsync(join(this._queuePath, bodyPath)).catch(() => {
fs.unlink(join(this._queuePath, bodyPath)).catch(() => {
// ignore
});
}
Expand Down
10 changes: 5 additions & 5 deletions test/unit/store.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { promises as fs } from 'fs';
import { join } from 'path';
import * as tmp from 'tmp';
import { afterEach, beforeEach, describe, expect, test } from 'vitest';

import { readFileAsync } from '../../src/main/fs';
import { BufferedWriteStore, Store } from '../../src/main/store';
import { delay, expectFilesInDirectory } from '../helpers';

Expand Down Expand Up @@ -30,7 +30,7 @@ describe('Store', () => {
await store.set({ num: 99, str: 'just a string' });
// It should have been written immediately
await expectFilesInDirectory(tempDir.name, 1);
const contents = await readFileAsync(join(tempDir.name, 'test-store.json'), 'utf-8');
const contents = await fs.readFile(join(tempDir.name, 'test-store.json'), 'utf-8');

expect(contents).to.equal('{"num":99,"str":"just a string"}');

Expand All @@ -57,19 +57,19 @@ describe('Store', () => {
await delay(1_000);
await expectFilesInDirectory(tempDir.name, 1);

const contents = await readFileAsync(join(tempDir.name, 'test-store.json'), 'utf-8');
const contents = await fs.readFile(join(tempDir.name, 'test-store.json'), 'utf-8');
expect(contents).to.equal('{"num":990,"str":"just a string"}');

await store.set({ num: 5_000, str: 'just a string' });
await delay(100);

// File should still contain the old value
const contents2 = await readFileAsync(join(tempDir.name, 'test-store.json'), 'utf-8');
const contents2 = await fs.readFile(join(tempDir.name, 'test-store.json'), 'utf-8');
expect(contents2).to.equal('{"num":990,"str":"just a string"}');

await delay(1_000);
// File should now contain updated value
const contents3 = await readFileAsync(join(tempDir.name, 'test-store.json'), 'utf-8');
const contents3 = await fs.readFile(join(tempDir.name, 'test-store.json'), 'utf-8');
expect(contents3).to.equal('{"num":5000,"str":"just a string"}');

// Load a new store instance so it's forced to read from disk
Expand Down

0 comments on commit 670e920

Please sign in to comment.