Исключение JavaScript / обработка ошибок не работает - PullRequest
2 голосов
/ 15 июня 2010

Это может быть немного трудно для понимания.

У меня есть функция внутри объекта:

f_openFRHandler:    function(input) {
            console.debug('f_openFRHandler');
            try{
                //throw 'foo';
                DragDrop.FileChanged(input);
                //foxyface.window.close();
            }
            catch(e){
                console.error(e);
                jQuery('#foxyface_open_errors').append('<div>Max local storage limit reached, unable to store new images in your browser. Please remove some images and try again.</div>');
            }
        },

внутри блока try, который он вызывает:

this.FileChanged = function(input) {
            // FileUploadManager.addFileInput(input);
            console.debug(input);
            var files = input.files;
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                if (!file.type.match(/image.*/)) continue;

                var reader = new FileReader();
                reader.onload = (function(f, isLast) {
                    return function(e) {
                        if (files.length == 1) {
                            LocalStorageManager.addImage(f.name, e.target.result, false, true);
                            LocalStorageManager.loadCurrentImage();
                            //foxyface.window.close();
                        }
                        else {
                            FileUploadManager.addFileData(f, e.target.result); // add multiple files to list
                            if (isLast) setTimeout(function() { LocalStorageManager.loadCurrentImage() },100);
                        }
                    };
                })(file, i == files.length - 1);
                reader.readAsDataURL(file);
            }
            return true;

LocalStorageManager.addImage вызывает:

this.setItem = function(data){
                localStorage.setItem('ImageStore', $.json_encode(data));
        }

localStorage.setItem выдает ошибку, если слишком много локального хранилища было использовано. Я хочу отловить эту ошибку в f_openFRHandler (первый пример кода), но она отправляется на консоль ошибок вместо блока catch. Я попробовал следующий код в моей консоли Firebug, чтобы убедиться, что я не сумасшедший, и он работает, как и ожидалось, несмотря на множество уровней вложенности функций:

try{
    (function(){
        (function(){
            throw 'foo'
        })()
    })()
}
catch(e){
    console.debug(e)
}

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 15 июня 2010
var reader = new FileReader();
                reader.onload = (function(f, isLast) {

Вероятно, в этом и заключается ваша проблема - FileReader, вероятно, вызывает onload асинхронно, в то время как ваш try / catch больше не находится в области видимости.В интерфейсе FileReader может быть доступна отдельная функция обработчика ошибок, или вам может потребоваться переместить попытку / перехват в анонимную функцию, которую вы передаете onread ().

2 голосов
/ 15 июня 2010

Я думаю, что проблема в том, что ошибка происходит позже, после того, как ваша функция f_openFRHandler завершена. Обратите внимание, что функция, в которой вызывается LocalStorageManager.addImage, устанавливается как обработчик onload в считывателе, а не вызывается немедленно. Он вызывается позже, асинхронно, когда данные загружаются.

Вам нужно будет поместить try..catch в анонимную функцию, создаваемую и назначенную этому событию, например ::10000

this.FileChanged = function(input) {
    // FileUploadManager.addFileInput(input);
    console.debug(input);
    var files = input.files;
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        if (!file.type.match(/image.*/)) continue;

        var reader = new FileReader();
        reader.onload = (function(f, isLast) {
            return function(e) {
                try {       // ADDED
                    if (files.length == 1) {
                        LocalStorageManager.addImage(f.name, e.target.result, false, true);
                        LocalStorageManager.loadCurrentImage();
                        //foxyface.window.close();
                    }
                    else {
                        FileUploadManager.addFileData(f, e.target.result); // add multiple files to list
                        if (isLast) setTimeout(function() { LocalStorageManager.loadCurrentImage() },100);
                    }
                }
                catch (err) { // ADDED
                    // YOUR HANDLING HERE
                }
            };
        })(file, i == files.length - 1);
        reader.readAsDataURL(file);
    }
    return true;
};

Ваш (превосходный) тестовый случай выполняет вызов синхронно, поэтому при попытке его обнаруживается ошибка. Это модель ближе к тому, что на самом деле происходит:

try{
    (function(){
        setTimeout(function(){  // Use setTimeout to model asynchronicity
            throw 'foo'
        }, 100);
    })()
}
catch(e){
    console.debug(e)
}
...