##// END OF EJS Templates
Add a WrappedError class
Jonathan Frederic -
Show More
@@ -606,7 +606,7 b' define(['
606 });
606 });
607 };
607 };
608
608
609 var load = function(class_name, module_name, registry) {
609 var load_class = function(class_name, module_name, registry) {
610 // Tries to load a class
610 // Tries to load a class
611 //
611 //
612 // Tries to load a class from a module using require.js, if a module
612 // Tries to load a class from a module using require.js, if a module
@@ -618,8 +618,7 b' define(['
618 if (module_name) {
618 if (module_name) {
619 require([module_name], function(module) {
619 require([module_name], function(module) {
620 if (module[class_name] === undefined) {
620 if (module[class_name] === undefined) {
621 console.error('Class '+class_name+' not found in module '+module_name)
621 reject(new Error('Class '+class_name+' not found in module '+module_name));
622 reject();
623 } else {
622 } else {
624 resolve(module[class_name]);
623 resolve(module[class_name]);
625 }
624 }
@@ -628,14 +627,18 b' define(['
628 if (registry && registry[class_name]) {
627 if (registry && registry[class_name]) {
629 resolve(registry[class_name]);
628 resolve(registry[class_name]);
630 } else {
629 } else {
631 console.error('Class '+class_name+' not found in registry ', registry);
630 reject(new Error({
632 reject();
631 message: 'Class '+class_name+' not found in registry ',
632 registry: registry
633 }));
633 }
634 }
634 }
635 }
635 });
636 });
636 };
637 };
637
638
638 var resolve_dict = function(d) {
639 var resolve_dict = function(d) {
640 // Resolve a promiseful dictionary.
641 // Returns a single Promise.
639 var keys = Object.keys(d);
642 var keys = Object.keys(d);
640 var values = [];
643 var values = [];
641 keys.forEach(function(key) {
644 keys.forEach(function(key) {
@@ -650,6 +653,46 b' define(['
650 });
653 });
651 };
654 };
652
655
656 var WrappedError = function(message, error){
657 // Wrappable Error class
658
659 // The Error class doesn't actually act on `this`. Instead it always
660 // returns a new instance of Error. Here we capture that instance so we
661 // can apply it's properties to `this`.
662 var tmp = Error.apply(this, [message]);
663
664 // Copy the properties of the error over to this.
665 var properties = Object.getOwnPropertyNames(tmp);
666 for (var i = 0; i < properties.length; i++) {
667 this[properties[i]] = tmp[properties[i]];
668 }
669
670 // Keep a stack of the original error messages.
671 if (error instanceof WrappedError) {
672 this.error_stack = error.error_stack;
673 } else {
674 this.error_stack = [error];
675 }
676 this.error_stack.push(tmp);
677
678 return this;
679 };
680
681 WrappedError.prototype = Object.create(Error.prototype, {});
682
683 var reject = function(message, log) {
684 // Creates a wrappable Promise rejection function.
685 //
686 // Creates a function that returns a Promise.reject with a new WrappedError
687 // that has the provided message and wraps the original error that
688 // caused the promise to reject.
689 return function(error) {
690 var wrapped_error = new WrappedError(message, error);
691 if (log) console.error(wrapped_error);
692 return Promise.reject(wrapped_error);
693 };
694 };
695
653 var utils = {
696 var utils = {
654 regex_split : regex_split,
697 regex_split : regex_split,
655 uuid : uuid,
698 uuid : uuid,
@@ -679,8 +722,10 b' define(['
679 XHR_ERROR : XHR_ERROR,
722 XHR_ERROR : XHR_ERROR,
680 wrap_ajax_error : wrap_ajax_error,
723 wrap_ajax_error : wrap_ajax_error,
681 promising_ajax : promising_ajax,
724 promising_ajax : promising_ajax,
682 load: load,
725 load_class: load_class,
683 resolve_dict: resolve_dict,
726 resolve_dict: resolve_dict,
727 WrappedError: WrappedError,
728 reject: reject,
684 };
729 };
685
730
686 // Backwards compatability.
731 // Backwards compatability.
@@ -67,18 +67,21 b' define(['
67 var content = msg.content;
67 var content = msg.content;
68 var that = this;
68 var that = this;
69
69
70 utils.load_class(content.target_name, content.target_module, this.targets)
70 return utils.load_class(content.target_name, content.target_module,
71 .then(function(target) {
71 this.targets).then(function(target) {
72
72 var comm = new Comm(content.target_name, content.comm_id);
73 var comm = new Comm(content.target_name, content.comm_id);
73 that.register_comm(comm);
74 that.register_comm(comm);
74 try {
75 try {
75 target(comm, msg);
76 target(comm, msg);
76 } catch (e) {
77 } catch (e) {
77 console.log("Exception opening new comm:", e, e.stack, msg);
78 comm.close();
78 comm.close();
79 that.unregister_comm(comm);
79 that.unregister_comm(comm);
80 var error = new utils.WrappedError("Exception opening new comm", e);
81 return Promise.reject(error);
80 }
82 }
81 }, $.proxy(console.error, console));
83 return comm;
84 }, utils.reject('Could not open comm', true));
82 };
85 };
83
86
84 CommManager.prototype.comm_close = function (msg) {
87 CommManager.prototype.comm_close = function (msg) {
@@ -48,26 +48,33 b' define(['
48 //--------------------------------------------------------------------
48 //--------------------------------------------------------------------
49 WidgetManager.prototype.display_view = function(msg, model) {
49 WidgetManager.prototype.display_view = function(msg, model) {
50 // Displays a view for a particular model.
50 // Displays a view for a particular model.
51 var cell = this.get_msg_cell(msg.parent_header.msg_id);
51 return new Promise(function(resolve, reject) {
52 if (cell === null) {
52 var cell = this.get_msg_cell(msg.parent_header.msg_id);
53 console.log("Could not determine where the display" +
53 if (cell === null) {
54 " message was from. Widget will not be displayed");
54 reject(new Error("Could not determine where the display" +
55 } else {
55 " message was from. Widget will not be displayed"));
56 var dummy = null;
56 } else {
57 if (cell.widget_subarea) {
57 var dummy = null;
58 dummy = $('<div />');
58 if (cell.widget_subarea) {
59 cell.widget_subarea.append(dummy);
59 dummy = $('<div />');
60 cell.widget_subarea.append(dummy);
61 }
62
63 var that = this;
64 this.create_view(model, {cell: cell}).then(function(view) {
65 that._handle_display_view(view);
66 if (dummy) {
67 dummy.replaceWith(view.$el);
68 }
69 view.trigger('displayed');
70 resolve(view);
71 }, function(error) {
72 reject(new utils.WrappedError('Could not display view', error));
73 });
60 }
74 }
75 });
61
76
62 var that = this;
77
63 this.create_view(model, {cell: cell}).then(function(view) {
64 that._handle_display_view(view);
65 if (dummy) {
66 dummy.replaceWith(view.$el);
67 }
68 view.trigger('displayed');
69 });
70 }
71 };
78 };
72
79
73 WidgetManager.prototype._handle_display_view = function (view) {
80 WidgetManager.prototype._handle_display_view = function (view) {
@@ -79,7 +86,7 b' define(['
79
86
80 if (view.additional_elements) {
87 if (view.additional_elements) {
81 for (var i = 0; i < view.additional_elements.length; i++) {
88 for (var i = 0; i < view.additional_elements.length; i++) {
82 this.keyboard_manager.register_events(view.additional_elements[i]);
89 this.keyboard_manager.register_events(view.additional_elements[i]);
83 }
90 }
84 }
91 }
85 }
92 }
@@ -87,7 +94,7 b' define(['
87
94
88 WidgetManager.prototype.create_view = function(model, options) {
95 WidgetManager.prototype.create_view = function(model, options) {
89 // Creates a promise for a view of a given model
96 // Creates a promise for a view of a given model
90 return utils.load(model.get('_view_name'), model.get('_view_module'),
97 return utils.load_class(model.get('_view_name'), model.get('_view_module'),
91 WidgetManager._view_types).then(function(ViewType) {
98 WidgetManager._view_types).then(function(ViewType) {
92
99
93 // If a view is passed into the method, use that view's cell as
100 // If a view is passed into the method, use that view's cell as
@@ -102,10 +109,7 b' define(['
102 view.listenTo(model, 'destroy', view.remove);
109 view.listenTo(model, 'destroy', view.remove);
103 view.render();
110 view.render();
104 return view;
111 return view;
105 }, function(error) {
112 }, utils.reject("Couldn't create a view for model id '" + String(model.id) + "'"));
106 console.error(error);
107 return Promise.reject(error);
108 });
109 };
113 };
110
114
111 WidgetManager.prototype.get_msg_cell = function (msg_id) {
115 WidgetManager.prototype.get_msg_cell = function (msg_id) {
@@ -177,7 +181,7 b' define(['
177 this.create_model({
181 this.create_model({
178 model_name: msg.content.data.model_name,
182 model_name: msg.content.data.model_name,
179 model_module: msg.content.data.model_module,
183 model_module: msg.content.data.model_module,
180 comm: comm});
184 comm: comm}).handle($.proxy(console.error, error));
181 };
185 };
182
186
183 WidgetManager.prototype.create_model = function (options) {
187 WidgetManager.prototype.create_model = function (options) {
@@ -215,17 +219,18 b' define(['
215
219
216 var that = this;
220 var that = this;
217 var model_id = comm.comm_id;
221 var model_id = comm.comm_id;
218 var model_promise = utils.load(options.model_name, options.model_module, WidgetManager._model_types)
222 var model_promise = utils.load_class(options.model_name, options.model_module, WidgetManager._model_types)
219 .then(function(ModelType) {
223 .then(function(ModelType) {
220 var widget_model = new ModelType(that, model_id, comm);
224 var widget_model = new ModelType(that, model_id, comm);
221 widget_model.once('comm:close', function () {
225 widget_model.once('comm:close', function () {
222 delete that._models[model_id];
226 delete that._models[model_id];
223 });
227 });
224 return widget_model;
228 return widget_model;
229
225 }, function(error) {
230 }, function(error) {
226 delete that._models[model_id];
231 delete that._models[model_id];
227 console.error(error);
232 var wrapped_error = new utils.WrappedError("Couldn't create model", error);
228 return Promise.reject(error);
233 return Promise.reject(wrapped_error);
229 });
234 });
230 this._models[model_id] = model_promise;
235 this._models[model_id] = model_promise;
231 return model_promise;
236 return model_promise;
@@ -322,7 +322,7 b' define(["widgets/js/manager",'
322 // Remember the view by id.
322 // Remember the view by id.
323 that.child_views[child_view.id] = child_view;
323 that.child_views[child_view.id] = child_view;
324 return child_view;
324 return child_view;
325 });
325 }, utils.reject("Couldn't create child view"));
326 },
326 },
327
327
328 pop_child_view: function(child_model) {
328 pop_child_view: function(child_model) {
@@ -4,8 +4,9 b''
4 define([
4 define([
5 "widgets/js/widget",
5 "widgets/js/widget",
6 "jqueryui",
6 "jqueryui",
7 "base/js/utils",
7 "bootstrap",
8 "bootstrap",
8 ], function(widget, $){
9 ], function(widget, $, utils){
9
10
10 var BoxView = widget.DOMWidgetView.extend({
11 var BoxView = widget.DOMWidgetView.extend({
11 initialize: function(){
12 initialize: function(){
@@ -84,7 +85,7 b' define(['
84 that.after_displayed(function() {
85 that.after_displayed(function() {
85 view.trigger('displayed');
86 view.trigger('displayed');
86 });
87 });
87 });
88 }, utils.reject("Couldn't add child view to box", true));
88 },
89 },
89 });
90 });
90
91
General Comments 0
You need to be logged in to leave comments. Login now