Improve error recovery when starting a recording

This helps return the microphone access to the user.
pull/21833/head
Travis Ralston 2021-05-05 22:30:22 -06:00
parent b5c25498c8
commit b61fe2f8e6
2 changed files with 89 additions and 68 deletions

View File

@ -73,7 +73,9 @@ class ConsoleLogger {
// Convert objects and errors to helpful things
args = args.map((arg) => {
if (arg instanceof Error) {
if (arg instanceof DOMException) {
return arg.message + ` (${arg.name} | ${arg.code}) ` + (arg.stack ? `\n${arg.stack}` : '');
} else if (arg instanceof Error) {
return arg.message + (arg.stack ? `\n${arg.stack}` : '');
} else if (typeof (arg) === 'object') {
try {

View File

@ -90,6 +90,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
}
private async makeRecorder() {
try {
this.recorderStream = await navigator.mediaDevices.getUserMedia({
audio: {
channelCount: CHANNELS,
@ -114,6 +115,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
// web audio API prefers this be done async to avoid holding the main thread with math.
const mxRecorderWorkletPath = document.body.dataset.vectorRecorderWorkletScript;
if (!mxRecorderWorkletPath) {
// noinspection ExceptionCaughtLocallyJS
throw new Error("Unable to create recorder: no worklet script registered");
}
await this.recorderContext.audioWorklet.addModule(mxRecorderWorkletPath);
@ -162,6 +164,23 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
newBuf.set(buf, this.buffer.length);
this.buffer = newBuf;
};
} catch (e) {
console.error("Error starting recording: ", e);
if (e instanceof DOMException) { // Unhelpful DOMExceptions are common - parse them sanely
console.error(`${e.name} (${e.code}): ${e.message}`);
}
// Clean up as best as possible
if (this.recorderStream) this.recorderStream.getTracks().forEach(t => t.stop());
if (this.recorderSource) this.recorderSource.disconnect();
if (this.recorder) this.recorder.close();
if (this.recorderContext) {
// noinspection ES6MissingAwait - not important that we wait
this.recorderContext.close();
}
throw e; // rethrow so upstream can handle it
}
}
private get audioBuffer(): Uint8Array {