Enroller
@Enroller
Немного авантюрист

Почему исключения не попадают в catch?

Здравствуйте

Немного контекста:
Я работаю с локальными файлами, загружаемыми пользователем.
С файлами я работаю из отдельного модуля FileAPI.
FileAPI

/**
 * Обрабатывает загруженный файл
 */

 export function  handleFile() {

        let inputType = this.dataset.type;
        let file = this.files[0];
        let fileType = file.type;
        let fileExtension = fileType.split('/');
        // let fileName = this.name;

        if (checkTypeMatching(inputType, fileType) === true) {
            if (checkFileExtension(fileType) === true) {
                renderFile(file, fileExtension);
            } else {
                switch (inputType) {
                    case 'image':
                        renderError(`Требуется формат png или jpg а не ${fileExtension[1]}`);
                        break;
                    case 'audio':
                        renderError(`Требуется формат wav а не ${fileExtension[1]}`);
                        break;
                }
            }
        } else {
            // renderError('Неверный тип файла');
            throw {message: 'Неверный тип файла'};
        }

}

/**
 * Создаёт DOM узел
 *
 * @param {File} file - Тип поля(data-type)
 * @param {string} type - Тип загруженного файла([type]/[extension])
 */
export function  renderFile(file, type){
    let node;
    if(type[0] === 'image'){
        node = document.createElement('img');
    } else if (type[0] === 'audio'){
        node = document.createElement('audio');
    }

    uploadFile(file)
                .then((url)=>{
                    return loadNode(node, url, type);
                })
                .then((node)=>{
                         // ui.renderNode(node);
                }).catch((e)=>{
                   renderError(e);
    });
}

/**
 * Читает локальный файл
 * @async
 * @param {File} file - Элемент списка files(FileAPI)
 * @returns {Promise} Возвращает ссылку на файл в виде строки Base64
 */
export function  uploadFile(file){
return new Promise(function(resolve){

    let reader = new FileReader();
    reader.onload = function(){
      resolve(reader.result);
  }
    reader.readAsDataURL(file);
});
}

/**
 * Присваивает HTMLElement ссылку на локальный файл и инициализирует его
 * @async
 * @param {HTMLElement} node - Узел, с которого был загружен файл
 * @param {string} url - Ссылка на локальный файл(base64)
 * @returns {Promise} Возвращает инициализированный HTMLElement
 */
export function  loadNode(node, url, type){
    return new Promise(function(resolve, reject){
        node.src = url;
        console.log(type[0]);
            node.onload = function() {
                resolve(node, url);
            }
            node.onloadeddata = function() {
            resolve(node, url);
        }
        node.onerror = function(e){
            reject('Невозможно прочитать файл');
        }
    })
}

/**
 * Обработка ошибок
 *
 * @param {*} error - Текст ошибки
 */
export function  renderError(error){
    console.log(error);
}

/**
 * Проверка расширения загружаемого файла
 *
 * @param {string} type - Тип файла([type]/[extension])
 * @returns {boolean}
 */
export function  checkFileExtension(type){
    return /^(audio|image)\/(wav|jpeg|png)/.test(type);
}

/**
 * Сверка типа поля и типа файла
 *
 * @param {string} inputType - Тип поля(data-type)
 * @param {string} fileType - Тип загруженного файла([type]/[extension])
 * @returns {boolean}
 */
export function  checkTypeMatching(inputType, fileType) {
    return !!(fileType.includes(inputType));
}



import * as FileAPI from './fileAPI.js';

 try{
        let localFiles = document.querySelectorAll('input[type=file]');

        if(localFiles.length > 0) {
            localFiles.forEach((item) => {
                item.addEventListener('change', FileAPI.handleFile, false );
            });
        }}catch(error){
        FileAPI.renderError(error.message);
    }

Всё в общем то работает именно так как я задумывал, но я хотел бы обрабатывать ошибки отлавливая throw внутри catch
Я заменил в функцииhandleFile обработчик одной из ошибок на throw {message: ''} и понял что мой catch его не ловит..
Консоль выдаёт Uncaught
Я догадываюсь что это связано с тем что в обработчике полей ввода я указываю ссылку на функцию, но видимо прогулял эту тему..

Заранее благодарю за участие

UPD : Для теста throw я вызываю в последних строчках
FileAPI.handleFile

export function  handleFile() {

        let inputType = this.dataset.type;
        let file = this.files[0];
        let fileType = file.type;
        let fileExtension = fileType.split('/');
        // let fileName = this.name;

        if (checkTypeMatching(inputType, fileType) === true) {
            if (checkFileExtension(fileType) === true) {
                renderFile(file, fileExtension);
            } else {
                switch (inputType) {
                    case 'image':
                        renderError(`Требуется формат png или jpg а не ${fileExtension[1]}`);
                        break;
                    case 'audio':
                        renderError(`Требуется формат wav а не ${fileExtension[1]}`);
                        break;
                }
            }
        } else {
            // renderError('Неверный тип файла');
            throw {message: 'Неверный тип файла'};
        }

}

  • Вопрос задан
  • 106 просмотров
Решения вопроса 1
MvcBox
@MvcBox
Software Engineer [C/C++/JS(for Node.js)/etc]
Блок try/catch не сработает, если исключение выбрасывается асинхронно (подозреваю, что именно это и происходит).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы