Repository: pedroslopez/whatsapp-web.js
File: src/structures/Message.js (JavaScript)

Code before:

            if (msg.mediaData.mediaStage != 'RESOLVED') {
                // try to resolve media
                await msg.downloadMedia({
                    downloadEvenIfExpensive: true, 
                    rmrReason: 1
                });
            }

            if (msg.mediaData.mediaStage.includes('ERROR')) {
                // media could not be downloaded
                return undefined;
            }

            try {
                const decryptedMedia = await window.Store.DownloadManager.downloadAndDecrypt({
                    directPath: msg.directPath,
                    encFilehash: msg.encFilehash,
                    filehash: msg.filehash,
                    mediaKey: msg.mediaKey,
                    mediaKeyTimestamp: msg.mediaKeyTimestamp,
                    type: msg.type,
                    signal: (new AbortController).signal
                });
    
                const data = window.WWebJS.arrayBufferToBase64(decryptedMedia);
    
                return {
                    data,
                    mimetype: msg.mimetype,
                    filename: msg.filename
                };
            } catch (e) {
                if(e.status && e.status === 404) return undefined;
                throw e;
            }
        }, this.id._serialized);

        if (!result) return undefined;
        return new MessageMedia(result.mimetype, result.data, result.filename);
    }

    /**
     * Deletes a message from the chat
     * @param {?boolean} everyone If true and the message is sent by the current user, will delete it for everyone in the chat.
     */
    async delete(everyone) {
        await this.client.pupPage.evaluate((msgId, everyone) => {
            let msg = window.Store.Msg.get(msgId);

            if (everyone && msg.id.fromMe && msg.canRevoke()) {

Review comment (bug):
EDIT: This belongs a few lines earlier when calling `downloadAndDecrypt` not here at the `arrayBufferToBase64` call

need an additional catch for the occasion when this error happens:
```
(node:9076) UnhandledPromiseRejectionWarning: Error: Evaluation failed: DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
    at t.default (https://web.whatsapp.com/bootstrap_qr.e715964683fa904d24c6.js:19:117764)
    at t.default (https://web.whatsapp.com/bootstrap_qr.e715964683fa904d24c6.js:10:86971)
    at https://web.whatsapp.com/bootstrap_qr.e715964683fa904d24c6.js:10:85750
    at Generator.next (<anonymous>)
    at t (https://web.whatsapp.com/vendor1~bootstrap_qr.01f767f6389d1d9e6832.js:2:35021)
    at s (https://web.whatsapp.com/vendor1~bootstrap_qr.01f767f6389d1d9e6832.js:2:35232)
    at q (https://web.whatsapp.com/bootstrap_qr.e715964683fa904d24c6.js:2:353990)
    at MutationObserver.H (https://web.whatsapp.com/bootstrap_qr.e715964683fa904d24c6.js:2:353571)
    at ExecutionContext._evaluateInternal (C:\dev\wtvr\whatsapp-export2\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async ExecutionContext.evaluate (C:\dev\wtvr\whatsapp-export2\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:110:16)
    at async Message.downloadMedia (C:\dev\wtvr\whatsapp-export2\node_modules\whatsapp-web.js\src\structures\Message.js:311:24)
    at async Statement.<anonymous> (C:\dev\wtvr\whatsapp-export2\index.js:340:43)
```

Code after:

            if (msg.mediaData.mediaStage != 'RESOLVED') {
                // try to resolve media
                await msg.downloadMedia({
                    downloadEvenIfExpensive: true, 
                    rmrReason: 1
                });
            }

            if (msg.mediaData.mediaStage.includes('ERROR') || msg.mediaData.mediaStage === 'FETCHING') {
                // media could not be downloaded
                return undefined;
            }

            try {
                const decryptedMedia = await window.Store.DownloadManager.downloadAndDecrypt({
                    directPath: msg.directPath,
                    encFilehash: msg.encFilehash,
                    filehash: msg.filehash,
                    mediaKey: msg.mediaKey,
                    mediaKeyTimestamp: msg.mediaKeyTimestamp,
                    type: msg.type,
                    signal: (new AbortController).signal
                });
    
                const data = window.WWebJS.arrayBufferToBase64(decryptedMedia);
    
                return {
                    data,
                    mimetype: msg.mimetype,
                    filename: msg.filename
                };
            } catch (e) {
                if(e.status && e.status === 404) return undefined;
                throw e;
            }
        }, this.id._serialized);

        if (!result) return undefined;
        return new MessageMedia(result.mimetype, result.data, result.filename);
    }

    /**
     * Deletes a message from the chat
     * @param {?boolean} everyone If true and the message is sent by the current user, will delete it for everyone in the chat.
     */
    async delete(everyone) {
        await this.client.pupPage.evaluate((msgId, everyone) => {
            let msg = window.Store.Msg.get(msgId);

            if (everyone && msg.id.fromMe && msg.canRevoke()) {