Skip to content

Commit

Permalink
fix(messaging): serialize error instance
Browse files Browse the repository at this point in the history
  • Loading branch information
tmkx committed Jan 30, 2024
1 parent 1eeae91 commit f064b9d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
6 changes: 4 additions & 2 deletions apps/ai-assistant/src/background/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ const genAIAtom = atom(async (get) => {
return apiKey ? new GoogleGenerativeAI(apiKey) : null;
});

store.sub(genAIAtom, () => {});
let genAI: GoogleGenerativeAI | null = null;
const updateGenAIInstance = () => store.get(genAIAtom).then((instance) => (genAI = instance));
updateGenAIInstance();
store.sub(genAIAtom, updateGenAIInstance);

setStreamHandler(async (message, subscriber) => {
const { data } = message;
if (data && typeof data === 'object' && 'prompt' in data && typeof data.prompt === 'string') {
const genAI = await store.get(genAIAtom);
if (!genAI) return subscriber.error('GenAI is not initialized');
const result = await genAI.getGenerativeModel({ model: 'gemini-pro' }).generateContentStream({
contents: [
Expand Down
5 changes: 4 additions & 1 deletion apps/ai-assistant/src/content-scripts/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ export const App = () => {
{ prompt: 'Translate the following text to Chinese:\n' + text },
{
next: (token) => setContent((prev) => prev + token),
error: () => setIsLoading(false),
error: (err) => {
console.log('Translate Error', { err });
setIsLoading(false);
},
complete: () => setIsLoading(false),
}
);
Expand Down
20 changes: 20 additions & 0 deletions packages/messaging/src/core/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,23 @@ it('should support relay stream', async () => {
expectMessagingIsNotLeaked(relay2);
expectMessagingIsNotLeaked(sender);
});

it('should serialize error message', async () => {
const { port1, port2 } = new MessageChannel();

const receiver = createMessaging(fromMessagePort(port1), {
async onStream(_message, _subscriber) {
throw new Error('Internal Error');
},
});
const sender = createMessaging(fromMessagePort(port2));

const { promise, resolve, reject } = withResolvers<void>();
sender.stream(null, { error: reject, complete: resolve });

await expect(promise).rejects.toBeTypeOf('string');
await expect(promise).rejects.toThrow('Internal Error');

expectMessagingIsNotLeaked(receiver);
expectMessagingIsNotLeaked(sender);
});
3 changes: 2 additions & 1 deletion packages/messaging/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ export function createMessaging(port: Port, options?: CreateMessagingOptions): M
const cleanup = await onStream.call(context, message.d, observer);
processingStreamCleanups.set(message.i, cleanup);
} catch (error) {
terminate({ error });
// Error is not serializable in `chrome.runtime.Port`
terminate({ error: error instanceof Error ? error.message : error });
}
break;
}
Expand Down

0 comments on commit f064b9d

Please sign in to comment.