Skip to content

Commit 22bdf46

Browse files
fix: prevent unnecessary /api/speech calls causing 500 errors (#2201)
1 parent bc8d90c commit 22bdf46

2 files changed

Lines changed: 69 additions & 42 deletions

File tree

code/frontend/src/components/Answer/Answer.test.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -736,10 +736,9 @@ describe("Answer.tsx", () => {
736736
});
737737
test('test the api thow error', async () => {
738738
(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: false })
739-
const consoleSpy = jest.spyOn(console, 'log');
740-
let renderref
739+
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => undefined);
741740
await act(async () => {
742-
renderref = render(
741+
render(
743742
<Answer
744743
answer={{
745744
answer: componentPropsWithCitations.answer.answer,
@@ -752,8 +751,15 @@ describe("Answer.tsx", () => {
752751
/>
753752
);
754753
});
754+
const playBtn = screen.getByRole('button', {
755+
name: /speak/i
756+
});
757+
758+
await act(async () => {
759+
fireEvent.click(playBtn);
760+
});
761+
755762
expect(consoleSpy).toHaveBeenCalled();
756-
// Restore the original console.log
757763
consoleSpy.mockRestore();
758764
});
759765
// test('test speech', async () => {

code/frontend/src/components/Answer/Answer.tsx

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,16 @@ export const Answer = ({
6969
toggleIsRefAccordionOpen();
7070
};
7171

72-
const initializeSynthesizer = () => {
72+
const initializeSynthesizer = (
73+
token: string = synthesizerData.token,
74+
region: string = synthesizerData.region
75+
) => {
76+
if (!token || !region) {
77+
return null;
78+
}
7379
const speechConfig = sdk.SpeechConfig.fromAuthorizationToken(
74-
synthesizerData.token,
75-
synthesizerData.region
80+
token,
81+
region
7682
);
7783
const newAudioDestination = new SpeechSDK.SpeakerAudioDestination();
7884
const audioConfig =
@@ -87,41 +93,32 @@ export const Answer = ({
8793
clearTimeout(playbackTimeout);
8894
}
8995
setRemainingDuration(0);
96+
return newSynthesizer;
9097
};
9198

9299
useEffect(() => {
93-
if (synthesizerData.token != "") {
94-
initializeSynthesizer();
95-
96-
return () => {
97-
if (synthesizer) {
98-
synthesizer.close();
99-
}
100-
if (audioDestination) {
101-
audioDestination.close();
102-
}
103-
if (playbackTimeout) {
104-
clearTimeout(playbackTimeout);
105-
}
106-
};
107-
}
108-
}, [index, synthesizerData]);
109-
110-
useEffect(() => {
111-
const fetchSythesizerData = async () => {
112-
const response = await fetch("/api/speech");
113-
try {
114-
if (!response.ok) {
115-
throw new Error("Network response was not ok");
116-
}
117-
const data = await response.json();
118-
setSynthesizerData({ token: data.token, region: data.region });
119-
} catch (e) {
120-
console.log(e);
100+
return () => {
101+
if (synthesizer) {
102+
synthesizer.close();
103+
}
104+
if (audioDestination) {
105+
audioDestination.close();
106+
}
107+
if (playbackTimeout) {
108+
clearTimeout(playbackTimeout);
121109
}
122110
};
123-
fetchSythesizerData();
124-
}, []);
111+
}, [synthesizer, audioDestination, playbackTimeout]);
112+
113+
const fetchSythesizerData = async (): Promise<{ token: string; region: string }> => {
114+
const response = await fetch("/api/speech");
115+
if (!response.ok) {
116+
throw new Error("Network response was not ok");
117+
}
118+
const data = await response.json();
119+
setSynthesizerData({ token: data.token, region: data.region });
120+
return { token: data.token, region: data.region };
121+
};
125122

126123
useEffect(() => {
127124
if (!isActive && synthesizer && isSpeaking) {
@@ -193,10 +190,12 @@ export const Answer = ({
193190
return "";
194191
};
195192

196-
const startSpeech = () => {
197-
if (synthesizer) {
193+
const startSpeech = (
194+
activeSynthesizer: SpeechSDK.SpeechSynthesizer | null = synthesizer
195+
) => {
196+
if (activeSynthesizer) {
198197
const text = getAnswerText();
199-
synthesizer?.speakTextAsync(
198+
activeSynthesizer.speakTextAsync(
200199
text,
201200
(result) => {
202201
if (
@@ -261,8 +260,30 @@ export const Answer = ({
261260
}
262261
}
263262
} else {
264-
onSpeak(index, "speak", resetSpeech);
265-
startSpeech();
263+
const startSpeechPlayback = async () => {
264+
try {
265+
if (!synthesizer) {
266+
let token = synthesizerData.token;
267+
let region = synthesizerData.region;
268+
if (!synthesizerData.token || !synthesizerData.region) {
269+
const speechData = await fetchSythesizerData();
270+
token = speechData.token;
271+
region = speechData.region;
272+
}
273+
const newSynthesizer = initializeSynthesizer(token, region);
274+
onSpeak(index, "speak", resetSpeech);
275+
startSpeech(newSynthesizer);
276+
return;
277+
}
278+
279+
onSpeak(index, "speak", resetSpeech);
280+
startSpeech();
281+
} catch (error) {
282+
console.error("Error initializing speech synthesis:", error);
283+
}
284+
};
285+
286+
void startSpeechPlayback();
266287
}
267288
};
268289

0 commit comments

Comments
 (0)