UNPKG

sku-pg

Version:

Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!

159 lines (144 loc) 5.34 kB
// Copyright 2007 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview Error handling utilities. * * */ goog.provide('goog.debug.ErrorHandler'); goog.require('goog.debug'); goog.require('goog.debug.Trace'); /** * The ErrorHandler can be used to to wrap functions with a try/catch * statement. If an exception is thrown, the given error handler function will * be called. * * @constructor * @param {Function} handler Handler for exceptions. */ goog.debug.ErrorHandler = function(handler) { /** * Handler for exceptions, which can do logging, reporting, etc. * @type {Function} * @private */ this.errorHandlerFn_ = handler; }; /** * Private helper function to return a span that can be clicked on to display * an alert with the current stack trace. Newlines are replaced with a * placeholder so that they will not be html-escaped. * @param {string} stackTrace The stack trace to create a span for. * @return {string} A span which can be clicked on to show the stack trace. * @private */ goog.debug.ErrorHandler.prototype.getStackTraceHolder_ = function(stackTrace) { var buffer = []; buffer.push('##PE_STACK_START##'); buffer.push(stackTrace.replace(/(\r\n|\r|\n)/g, '##STACK_BR##')); buffer.push('##PE_STACK_END##'); return buffer.join(''); }; /** * Installs exception protection for an entry point function. When an exception * is thrown from a protected function, a handler will be invoked to handle it. * * @param {Function} fn An entry point function to be protected. * @param {boolean=} opt_tracers Whether to install tracers around the fn. * @return {!Function} A protected wrapper function that calls the entry point * function. */ goog.debug.ErrorHandler.prototype.protectEntryPoint = function(fn, opt_tracers) { var tracers = !!opt_tracers; var protectedFnName = '__protected_' + goog.getUid(this) + '_' + tracers + '__'; if (!fn[protectedFnName]) { fn[protectedFnName] = this.getProtectedFunction(fn, tracers); } return fn[protectedFnName]; }; /** * Helps {@link #protectEntryPoint} by actually creating the protected * wrapper function, after {@link #protectEntryPoint} determines that one does * not already exist for the given function. Can be overriden by subclasses * that may want to implement different error handling, or add additional * entry point hooks. * @param {Function} fn An entry point function to be protected. * @param {boolean} tracers Whether to install tracers around fn. * @return {!Function} protected wrapper function. * @protected */ goog.debug.ErrorHandler.prototype.getProtectedFunction = function(fn, tracers) { var that = this; if (tracers) { var stackTrace = goog.debug.getStacktraceSimple(15); } return function() { if (tracers) { var tracer = goog.debug.Trace.startTracer('protectedEntryPoint: ' + that.getStackTraceHolder_(stackTrace)); } try { return fn.apply(this, arguments); } catch (e) { that.errorHandlerFn_(e); throw e; // Re-throw it since this may be expected by the caller. } finally { if (tracers) { goog.debug.Trace.stopTracer(tracer); } } }; }; /** * Installs exception protection for window.setTimeout to handle exceptions. * @param {boolean=} opt_tracers Whether to install tracers around the fn. */ goog.debug.ErrorHandler.prototype.protectWindowSetTimeout = function(opt_tracers) { var win = goog.getObjectByName('window'); var originalSetTimeout = win.setTimeout; var that = this; win.setTimeout = function(fn, time) { // IE doesn't support .call for setTimeout, but it also doesn't care // what "this" is, so we can just call the original function directly fn = that.protectEntryPoint(fn, opt_tracers); if (originalSetTimeout.call) { return originalSetTimeout.call(this, fn, time); } else { return originalSetTimeout(fn, time); } }; }; /** * Install exception protection for window.setInterval to handle exceptions. * @param {boolean=} opt_tracers Whether to install tracers around the fn. */ goog.debug.ErrorHandler.prototype.protectWindowSetInterval = function(opt_tracers) { var win = goog.getObjectByName('window'); var originalSetInterval = win.setInterval; var that = this; win.setInterval = function(fn, time) { // IE doesn't support .call for setInterval, but it also doesn't care // what "this" is, so we can just call the original function directly fn = that.protectEntryPoint(fn, opt_tracers); if (originalSetInterval.call) { return originalSetInterval.call(this, fn, time); } else { return originalSetInterval(fn, time); } }; };