Fix some type handling

This commit is contained in:
Will Scullin 2022-05-31 18:26:02 -07:00
parent d73ce20e95
commit af6a21d1df
No known key found for this signature in database
GPG Key ID: 26DCD1042C6638CD
5 changed files with 65 additions and 53 deletions

View File

@ -41,7 +41,7 @@ export const Apple2 = (props: Apple2Props) => {
const [apple2, setApple2] = useState<Apple2Impl>();
const [io, setIO] = useState<Apple2IO>();
const [cpu, setCPU] = useState<CPU6502>();
const [error, setError] = useState<string>();
const [error, setError] = useState<unknown>();
useEffect(() => {
if (screen.current) {
@ -59,13 +59,7 @@ export const Apple2 = (props: Apple2Props) => {
setCPU(cpu);
apple2.reset();
apple2.run();
}).catch((e) => {
if (e instanceof Error) {
setError(e.message);
} else {
console.error(e);
}
});
}).catch((e) => setError(e));
}
}, [props]);

View File

@ -40,19 +40,11 @@ export interface DiskIIProps extends DiskIIData {
export const DiskII = ({ disk2, number, on, name, side }: DiskIIProps) => {
const label = side ? `${name} - ${side}` : name;
const [modalOpen, setModalOpen] = useState(false);
const [error, setError] = useState<string>();
const [error, setError] = useState<unknown>();
const [currentHash, setCurrentHash] = useState<string>();
const hash = useHash();
const handleError = (e: unknown) => {
if (e instanceof Error) {
setError(e.message);
} else {
console.error(e);
}
};
useEffect(() => {
const hashParts = getHashParts(hash);
const newHash = hashParts[number];
@ -61,11 +53,11 @@ export const DiskII = ({ disk2, number, on, name, side }: DiskIIProps) => {
if (hashPart !== currentHash) {
if (hashPart.match(/^https?:/)) {
loadHttpFile(disk2, number, hashPart)
.catch((e) => handleError(e));
.catch((e) => setError(e));
} else {
const filename = `/json/disks/${hashPart}.json`;
loadJSON(disk2, number, filename)
.catch((e) => handleError(e));
.catch((e) => setError(e));
}
setCurrentHash(hashPart);
}

View File

@ -1,34 +1,45 @@
import { h, Fragment } from 'preact';
import { h } from 'preact';
import { useCallback } from 'preact/hooks';
import { Modal, ModalContent, ModalFooter } from './Modal';
export interface ErrorProps {
error: string | undefined;
error: unknown | undefined;
setError: (error: string | undefined) => void;
}
export const ErrorModal = ({ error, setError } : ErrorProps) => {
export const ErrorModal = ({ error, setError }: ErrorProps) => {
const onClose = useCallback(() => setError(undefined), [setError]);
let errorStr = null;
if (error) {
if (error instanceof Error) {
errorStr = error.message;
} else if (typeof error === 'string') {
errorStr = error;
} else {
errorStr = 'Unknown Error';
console.error(error);
}
}
return (
<>
{ error && (
<Modal
title="Error"
icon="triangle-exclamation"
isOpen={true}
onClose={onClose}
>
<ModalContent>
<div style={{ width: 320, fontSize: '1.1em', padding: '5px 11px'}}>
{error}
</div>
</ModalContent>
<ModalFooter>
<button onClick={onClose}>OK</button>
</ModalFooter>
</Modal>
)}
</>
);
if (errorStr) {
return (
<Modal
title="Error"
icon="triangle-exclamation"
isOpen={true}
onClose={onClose}
>
<ModalContent>
<div style={{ width: 320, fontSize: '1.1em', padding: '5px 11px' }}>
{errorStr}
</div>
</ModalContent>
<ModalFooter>
<button onClick={onClose}>OK</button>
</ModalFooter>
</Modal>
);
} else {
return null;
}
};

View File

@ -52,7 +52,7 @@ export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) =>
const [category, setCategory] = useState<string>();
const [handles, setHandles] = useState<FileSystemFileHandleLike[]>();
const [filename, setFilename] = useState<string>();
const [error, setError] = useState<string>();
const [error, setError] = useState<unknown>();
const hash = useHash();
const doCancel = useCallback(() => onClose(true), [onClose]);
@ -72,11 +72,7 @@ export const FileModal = ({ disk2, number, onClose, isOpen }: FileModalProps) =>
await loadJSON(disk2, number, filename);
}
} catch (e) {
if (e instanceof Error) {
setError(e.message);
} else {
console.error(e);
}
setError(e);
} finally {
setHashParts(hashParts);
setBusy(false);

View File

@ -9,7 +9,17 @@ describe('ErrorModal', () => {
it('renders when there is an error', () => {
const setError = jest.fn();
render(
<ErrorModal error="My Error" setError={setError} />
<ErrorModal error={new Error('My Error')} setError={setError} />
);
expect(screen.queryByRole('banner')).toBeVisible();
expect(screen.queryByRole('banner')).toHaveTextContent('Error');
expect(screen.queryByText('My Error')).toBeVisible();
});
it('renders when there is an error string', () => {
const setError = jest.fn();
render(
<ErrorModal error={'My Error'} setError={setError} />
);
expect(screen.queryByRole('banner')).toBeVisible();
expect(screen.queryByRole('banner')).toHaveTextContent('Error');
@ -18,11 +28,20 @@ describe('ErrorModal', () => {
it('does not render when there is not an error', () => {
const setError = jest.fn();
render(
const { container } = render(
<ErrorModal error={undefined} setError={setError} />
);
expect(screen.queryByRole('banner')).not.toBeInTheDocument();
expect(screen.queryByText('My Error')).not.toBeInTheDocument();
expect(container).toBeEmptyDOMElement();
});
it('handles an invalid error', () => {
jest.spyOn(console, 'error').mockImplementation();
const setError = jest.fn();
render(
<ErrorModal error={{foo: 'My Error'}} setError={setError} />
);
expect(screen.queryByText('Unknown Error')).toBeVisible();
expect(console.error).toHaveBeenCalledWith({foo: 'My Error'});
});
it('calls setError when close is clicked', () => {