Пример #1
0
    def _post_data(self, context):
        """POST data to the the Exceptional API. If DEBUG is True then data is
        sent to ``EXCEPTIONAL_DEBUG_URL`` if it has been defined. If TESTING is
        true, error data is stored in the global ``flask.g.exceptional`` variable.
        
        :param context: The current application context.
        """
        traceback = tbtools.get_current_traceback()
        error_data = json.dumps({
            "application_environment": self.__get_application_data(context.app),
            "client": context.app.extensions["exceptional"],
            "request": self.__get_request_data(context.app, context.request, context.session),
            "exception": self.__get_exception_data(traceback)
        })
        
        if context.app.testing:
            g.exceptional = error_data
        
        if self.url:
            request = Request(self.url)
            request.add_header("Content-Type", "application/json")
            
            if context.app.debug:
                data = error_data
            else:
                request.add_header("Content-Encoding", "deflate")
                data = compress(error_data, 1)
            
            try:
                urlopen(request, data)
            except URLError:
                message = "Unable to connect to {0}. See \
http://status.getexceptional.com for details. Error data:\n{1}".format(self.url, error_data)
                self.app.logger.warning(message, exc_info=True)
Пример #2
0
def send_exception(subject):
    """Send Python exception tracebacks via email to the ADMINS list.

    Use the same HTML styling as Flask tracebacks in debug web servers.

    This function must be called while the exception is happening. It picks up the raised exception with sys.exc_info().

    Positional arguments:
    subject -- subject line of the email (to be prepended by 'Application Error: ').
    """
    # Generate and modify html.
    tb = tbtools.get_current_traceback()  # Get exception information.
    with _override_html():
        html = tb.render_full().encode('utf-8', 'replace')
    html = html.replace('<blockquote>', '<blockquote style="margin: 1em 0 0; padding: 0;">')
    subject = 'Application Error: {}'.format(subject)

    # Apply throttle.
    md5 = hashlib.md5('{}{}'.format(subject, html)).hexdigest()
    seconds = int(current_app.config['MAIL_EXCEPTION_THROTTLE'])
    lock = redis.lock(EMAIL_THROTTLE.format(md5=md5), timeout=seconds)
    have_lock = lock.acquire(blocking=False)
    if not have_lock:
        current_app.logger.debug('Suppressing email: {}'.format(subject))
        return

    # Send email.
    msg = Message(subject=subject, recipients=current_app.config['ADMINS'], html=html)
    mail.send(msg)
Пример #3
0
def send_exception(subject):
    """Send Python exception tracebacks via email to the ADMINS list.

    Use the same HTML styling as Flask tracebacks in debug web servers.

    This function must be called while the exception is happening. It picks up the raised exception with sys.exc_info().

    Positional arguments:
    subject -- subject line of the email (to be prepended by 'Application Error: ').
    """
    # Generate and modify html.
    tb = tbtools.get_current_traceback()  # Get exception information.
    with _override_html():
        html = tb.render_full().encode('utf-8', 'replace')
    html = html.replace('<blockquote>',
                        '<blockquote style="margin: 1em 0 0; padding: 0;">')
    subject = 'Application Error: {}'.format(subject)

    # Apply throttle.
    # I should apply a throttle here, but the template uses redis, and I'm not planning on having that...

    # Send email.
    msg = Message(subject=subject,
                  recipients=current_app.config['ADMINS'],
                  html=html)
    mail.send(msg)
Пример #4
0
def json_response(f, *args, **kwargs):
    try:
        response = f(*args, **kwargs)

    except HTTPException as e:
        data = {'error': str(e),
                'description': e.description}
        return jsonify(data), e.code

    except Exception as e:
        app.logger.error('Exception during json request: %r', e)
        # Werkzeug sends the response and then logs, which is fiddly
        from werkzeug.debug.tbtools import get_current_traceback
        traceback = get_current_traceback(ignore_system_exceptions=True)
        app.logger.info('Traceback %s', traceback.plaintext)

        data = {'error': e.__class__.__name__,
                'description': str(e)}
        return jsonify(data), 500

    else:
        if isinstance(response, (app.response_class, BaseResponse)):
            return response

        return jsonify(response), 200
Пример #5
0
    def debug_application(self, environ, start_response):
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item

            if hasattr(app_iter, 'close'):
                app_iter.close()
        except:
            if hasattr(app_iter, 'close'):
                app_iter.close()
            traceback = get_current_traceback(skip=1, show_hidden_frames=self.show_hidden_frames, ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame

            self.tracebacks[traceback.id] = traceback
            try:
                start_response('500 INTERNAL SERVER ERROR', [('Content-Type', 'text/html; charset=utf-8')])
            except:
                environ['wsgi.errors'].write('Debugging middleware caught exception in streamed response at a point where response headers were already sent.\n')
            else:
                yield traceback.render_full(evalex=self.evalex).encode('utf-8', 'replace')

            traceback.log(environ['wsgi.errors'])
Пример #6
0
def send_exception(subject):
    """Send Python exception tracebacks via email to the ADMINS list.

    Use the same HTML styling as Flask tracebacks in debug web servers.

    This function must be called while the exception is happening.
    It picks up the raised exception with sys.exc_info().

    Positional arguments:
    subject -- subject line of the email.
    """
    # Generate and modify html.
    tb = tbtools.get_current_traceback()  # Get exception information.
    with _override_html():
        html = tb.render_full().encode('utf-8', 'replace')
    html = html.replace('<blockquote>',
                        '<blockquote style="margin: 1em 0 0; padding: 0;">')
    subject = '[FRLA.mobile CMS] Application Error: {}'.format(subject)

    # Send email.
    mail.send_email(
        subject=subject,
        to=[{
            'email%s' % idx: email
            for idx, email in enumerate(current_app.config['ADMINS'])
        }],
        html=html)
Пример #7
0
    def __call__(self, error):
        template_fname = self.data_browser.error_template

        if isinstance(error, PermissionDenied):
            permissions = []
            for idx, need in enumerate(error.args[0].needs):
                permissions.append(str(need))
            err_msg = _(
                u'this operation needs the following permissions: %(permissions)s, contact administrator to grant '
                u'them!',
                permissions=";".join(permissions))
        elif isinstance(error, ValidationError):
            err_msg = ",".join("%s: %s" % (k, v) for k, v in error.args[0].items())
        elif isinstance(error, NotFound):
            err_msg = _("Sorry, object doesn't exist!")
        else:
            # we need to log the crime scene
            # note, this is the last line of defence, we must resolve it here!
            traceback = get_current_traceback(skip=1, show_hidden_frames=False,
                                              ignore_system_exceptions=True)
            self.data_browser.app.logger.error("%s %s" % (request.method, request.url))
            self.data_browser.app.logger.error(traceback.plaintext)
            err_msg = _(u'Internal error "%(err)s", please contact us!', err=str(error))

        return render_template(template_fname, hint_message=err_msg, error=error,
                               back_url=request.args.get("url", "/"))
Пример #8
0
def send_exception(subject):
    """Send Python exception tracebacks via email to the ADMINS list.

    Use the same HTML styling as Flask tracebacks in debug web servers.

    This function must be called while the exception is happening. It picks up the raised exception with sys.exc_info().

    Positional arguments:
    subject -- subject line of the email (to be prepended by 'Application Error: ').
    """
    # Generate and modify html.
    tb = tbtools.get_current_traceback()  # Get exception information.
    with _override_html():
        html = tb.render_full().encode('utf-8', 'replace')
    html = html.replace('<blockquote>',
                        '<blockquote style="margin: 1em 0 0; padding: 0;">')
    subject = 'Application Error: {}'.format(subject)

    # Apply throttle.
    md5 = hashlib.md5('{}{}'.format(subject, html)).hexdigest()
    seconds = int(current_app.config['MAIL_EXCEPTION_THROTTLE'])
    lock = redis.lock(EMAIL_THROTTLE.format(md5=md5), timeout=seconds)
    have_lock = lock.acquire(blocking=False)
    if not have_lock:
        current_app.logger.debug('Suppressing email: {}'.format(subject))
        return

    # Send email.
    msg = Message(subject=subject,
                  recipients=current_app.config['ADMINS'],
                  html=html)
    mail.send(msg)
Пример #9
0
    def debug_application(self, environ, start_response):
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item

            if hasattr(app_iter, 'close'):
                app_iter.close()
        except:
            if hasattr(app_iter, 'close'):
                app_iter.close()
            traceback = get_current_traceback(
                skip=1,
                show_hidden_frames=self.show_hidden_frames,
                ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame

            self.tracebacks[traceback.id] = traceback
            try:
                start_response('500 INTERNAL SERVER ERROR',
                               [('Content-Type', 'text/html; charset=utf-8')])
            except:
                environ['wsgi.errors'].write(
                    'Debugging middleware caught exception in streamed response at a point where response headers were already sent.\n'
                )
            else:
                yield traceback.render_full(evalex=self.evalex).encode(
                    'utf-8', 'replace')

            traceback.log(environ['wsgi.errors'])
Пример #10
0
def json_response(f, *args, **kwargs):
    try:
        response = f(*args, **kwargs)

    except HTTPException as e:
        data = {'error': str(e),
                'description': e.description}
        return jsonify(data), e.code

    except Exception as e:
        app.logger.error('Exception during json request: %r', e)
        # Werkzeug sends the response and then logs, which is fiddly
        from werkzeug.debug.tbtools import get_current_traceback
        traceback = get_current_traceback(ignore_system_exceptions=True)
        app.logger.info('Traceback %s', traceback.plaintext)

        data = {'error': e.__class__.__name__,
                'description': str(e)}
        return jsonify(data), 500

    else:
        if isinstance(response, (app.response_class, BaseResponse)):
            return response

        return jsonify(response), 200
Пример #11
0
 def errorlog(exception):
     """ We want to log exception information to file for later investigation """
     traceback = get_current_traceback(ignore_system_exceptions=True, show_hidden_frames=True)
     log.error(traceback.plaintext)
     last = traceback.frames[-1]
     now = datetime.datetime.now().replace(microsecond=0)
     return render_template("error.html", now=now, name=os.path.basename(last.filename), line=last.lineno, exception=exception)
Пример #12
0
    async def _debug_application(self, message, channels):
        """Run the application and conserve the traceback frames."""
        try:
            await self.app(message, channels)
        except Exception:
            traceback = get_current_traceback(
                skip=1,
                show_hidden_frames=self.show_hidden_frames,
                ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            status = 500
            headers = [
                (b'Content-Type', b'text/html; charset=utf-8'),
                # Disable Chrome's XSS protection, the debug
                # output can cause false-positives.
                (b'X-XSS-Protection', b'0'),
            ]
            environ = utils.message_to_environ(message)
            is_trusted = bool(self.check_pin_trust(environ))
            content = traceback.render_full(evalex=self.evalex,
                                            evalex_trusted=is_trusted,
                                            secret=self.secret).encode(
                                                'utf-8', 'replace')
            await channels['reply'].send({
                'status': status,
                'headers': headers,
                'content': content
            })
Пример #13
0
 async def asgi_wrapper(receive, send):
     try:
         return await application(receive, send)
     except Exception:
         traceback = get_current_traceback(
             skip=1,
             show_hidden_frames=self.show_hidden_frames,
             ignore_system_exceptions=True)
         for frame in traceback.frames:
             self.frames[frame.id] = frame
         self.tracebacks[traceback.id] = traceback
         environ = utils.message_to_environ(self.scope)
         is_trusted = sync_to_async(self.check_pin_trust)(environ)
         _traceback = traceback.render_full(evalex=self.evalex,
                                            evalex_trusted=is_trusted,
                                            secret=self.secret).encode(
                                                'utf-8', 'replace')
         headers = [
             (b'Content-Type', b'text/html; charset=utf-8'),
             # Disable Chrome's XSS protection, the debug
             # output can cause false-positives.
             (b'X-XSS-Protection', b'0'),
         ]
         response = http_response(self.scope,
                                  body=_traceback,
                                  status=500,
                                  headers=headers)
         return await response(receive, send)
Пример #14
0
    def debug_application(self, environ, start_response):
        """Run the application and conserve the traceback frames."""
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item
            if hasattr(app_iter, "close"):
                app_iter.close()
        except Exception:
            if hasattr(app_iter, "close"):
                app_iter.close()
            traceback = get_current_traceback(
                skip=1, show_hidden_frames=self.show_hidden_frames, ignore_system_exceptions=True
            )
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            try:
                start_response("500 INTERNAL SERVER ERROR", [("Content-Type", "text/html; charset=utf-8")])
            except Exception:
                # if we end up here there has been output but an error
                # occurred.  in that situation we can do nothing fancy any
                # more, better log something into the error log and fall
                # back gracefully.
                environ["wsgi.errors"].write(
                    "Debugging middleware caught exception in streamed "
                    "response at a point where response headers were already "
                    "sent.\n"
                )
            else:
                yield traceback.render_full(evalex=self.evalex).encode("utf-8", "replace")

            traceback.log(environ["wsgi.errors"])
Пример #15
0
 def get_current_traceback(self):
     "Get the current Python traceback, keeping stack frames in debug app."
     traceback = get_current_traceback()
     for frame in traceback.frames:
         self.debug_app.frames[frame.id] = frame
     self.debug_app.tracebacks[traceback.id] = traceback
     return traceback
Пример #16
0
 def get_current_traceback(self):
     "Get the current Python traceback, keeping stack frames in debug app."
     # https://gist.github.com/rduplain/4983839
     traceback = get_current_traceback()
     for frame in traceback.frames:
         self.debug_app.frames[frame.id] = frame
     self.debug_app.tracebacks[traceback.id] = traceback
     return traceback
Пример #17
0
        def wrapper(request):
            try:
                response = func(request)
            except Exception as e:
                tb = get_current_traceback()
                return responses.InternalServerError(render_function(tb), headers={"Content-type": content_type})

            return response
Пример #18
0
def get_current_traceback():
    "Get the current traceback in debug mode, using werkzeug debug tools."
    # Lazy import statement, as debugger is only used in development.
    from werkzeug.debug.tbtools import get_current_traceback
    # Experiment with skip argument, to skip stack frames in traceback.
    traceback = get_current_traceback(skip=2, show_hidden_frames=False,
                                      ignore_system_exceptions=True)
    return traceback
Пример #19
0
def exception_handler(e):
    tb = get_current_traceback()
    last_frame = tb.frames[-1]
    last_frame_args = inspect.getargs(last_frame.code)
    return render_template('show_error.html',
                           tb=tb,
                           last_frame=last_frame,
                           last_frame_args=last_frame_args), 500
Пример #20
0
    def render_exception(self):
        traceback = get_current_traceback()

        for frame in traceback.frames:
            self.debugger.frames[frame.id] = frame
        self.debugger.tracebacks[traceback.id] = traceback

        return traceback.render_full(evalex=True, secret=self.debugger.secret)
Пример #21
0
def nfmp():
    try:
        content = request.get_json()
        return jsonify(run_nfmp(content))
    except Exception as e:
        track = get_current_traceback(skip=1, show_hidden_frames=True,
                    ignore_system_exceptions=False)
        track.log()
        abort(500)
    def render_exception(self):
        traceback = get_current_traceback()

        for frame in traceback.frames:
            self.debugger.frames[frame.id] = frame
        self.debugger.tracebacks[traceback.id] = traceback

        return traceback.render_full(evalex=True,
                                     secret=self.debugger.secret)
Пример #23
0
def exception_handler(e):
    tb = get_current_traceback()
    last_frame = next(frame for frame in reversed(tb.frames)
                      if not frame.is_library)
    last_frame_args = inspect.getargs(last_frame.code)
    return render_template('show_error.html',
                           tb=tb,
                           last_frame=last_frame,
                           last_frame_args=last_frame_args), 500
Пример #24
0
        def wrapper(request, *args, **kwargs):
            try:
                response = func(request, *args, **kwargs)
            except Exception:
                tb = get_current_traceback()
                return responses.InternalServerError(
                    render_function(tb),
                    headers={"Content-type": content_type})

            return response
Пример #25
0
def exception_handler(e):
    tb = get_current_traceback()
    return render_template('show_error.html', tb=tb), 500

    exc_type, exc_value, tb = sys.exc_info()

    if exc_value is e:
        reraise(exc_type, exc_value, tb)
    else:
        raise e
Пример #26
0
        def _wrap_errors(_):
            """Install traceback handling for callbacks"""
            self._traceback = sys.exc_info()[2]

            # Compute number of stack frames to skip to get down to callback
            tb_werkzeug = get_current_traceback()
            skip = 0
            if dev_tools_prune_errors:
                for i, line in enumerate(tb_werkzeug.plaintext.splitlines()):
                    if "%% callback invoked %%" in line:
                        skip = int((i + 1) / 2)
                        break

            # Customized formatargvalues function so we can place function parameters
            # on separate lines
            original_formatargvalues = inspect.formatargvalues
            inspect.formatargvalues = _custom_formatargvalues
            try:
                # Use IPython traceback formatting to build colored ANSI traceback
                # string
                ostream = io.StringIO()
                ipytb = FormattedTB(
                    tb_offset=skip,
                    mode="Verbose",
                    color_scheme="Linux",
                    include_vars=True,
                    ostream=ostream
                )
                ipytb()
            finally:
                # Restore formatargvalues
                inspect.formatargvalues = original_formatargvalues

            # Print colored ANSI representation if requested
            ansi_stacktrace = ostream.getvalue()

            if inline_exceptions:
                print(ansi_stacktrace)

            # Use ansi2html to convert the colored ANSI string to HTML
            conv = Ansi2HTMLConverter(scheme="ansi2html", dark_bg=False)
            html_str = conv.convert(ansi_stacktrace)

            # Set width to fit 75-character wide stack trace and font to a size the
            # won't require a horizontal scroll bar
            html_str = html_str.replace(
                '<html>',
                '<html style="width: 75ch; font-size: 0.86em">'
            )

            # Remove explicit background color so Dash dev-tools can set background
            # color
            html_str = re.sub("background-color:[^;]+;", "", html_str)

            return html_str, 500
Пример #27
0
Файл: web.py Проект: HVF/diesel
 def handle_request(self, req):
     with self.request_context(req):
         try:
             response = self.full_dispatch_request()
         except Exception, e:
             self.log_exception(e)
             try:
                 response = self.make_response(self.handle_exception(e))
             except:
                 tb = tbtools.get_current_traceback(skip=1)
                 response = Response(tb.render_summary(), headers={'Content-Type' : 'text/html'})
Пример #28
0
 def handle_request(self, req):
     with self.request_context(req):
         try:
             response = self.full_dispatch_request()
         except Exception, e:
             self.log_exception(e)
             try:
                 response = self.make_response(self.handle_exception(e))
             except:
                 tb = tbtools.get_current_traceback(skip=1)
                 response = Response(tb.render_summary(),
                                     headers={'Content-Type': 'text/html'})
Пример #29
0
    def error(error):
        if isinstance(error, SQLAlchemyError):
            from lite_mms.database import db

            db.session.rollback()
        from werkzeug.debug.tbtools import get_current_traceback

        traceback = get_current_traceback(skip=1, show_hidden_frames=False,
                                          ignore_system_exceptions=True)
        app.logger.error("%s %s" % (request.method, request.url))
        app.logger.error(traceback.plaintext)
        sender_email(traceback)
        return redirect(url_for("error", errors=u"%s %s时,系统异常" % (request.method, request.url),
                                detail=traceback.render_summary(), url=request.args.get("url", "/")))
Пример #30
0
 def error(error):
     if isinstance(error, SQLAlchemyError):
         from cloud_dashing.database import db
         db.session.rollback()
     from werkzeug.debug.tbtools import get_current_traceback
     traceback = get_current_traceback(skip=1, show_hidden_frames=False,
                                       ignore_system_exceptions=True)
     app.logger.error("%s %s" % (request.method, request.url))
     app.logger.error(traceback.plaintext)
     sender_email(traceback)
     return render_template("error.html",
                            error=_("Failed to %(method)s %(url)s",
                                    method=request.method, url=request.url),
                            detail=traceback.render_summary(),
                            back_url=request.args.get("__back_url__", "/"))
Пример #31
0
    def debug_application(self, environ, start_response):
        """Run the application and conserve the traceback frames."""
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item
            if hasattr(app_iter, "close"):
                app_iter.close()
        except Exception:
            if hasattr(app_iter, "close"):
                app_iter.close()
            traceback = get_current_traceback(
                skip=1,
                show_hidden_frames=self.show_hidden_frames,
                ignore_system_exceptions=True,
            )
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            try:
                start_response(
                    "500 INTERNAL SERVER ERROR",
                    [
                        ("Content-Type", "text/html; charset=utf-8"),
                        # Disable Chrome's XSS protection, the debug
                        # output can cause false-positives.
                        ("X-XSS-Protection", "0"),
                    ],
                )
            except Exception:
                # if we end up here there has been output but an error
                # occurred.  in that situation we can do nothing fancy any
                # more, better log something into the error log and fall
                # back gracefully.
                environ["wsgi.errors"].write(
                    "Debugging middleware caught exception in streamed "
                    "response at a point where response headers were already "
                    "sent.\n"
                )
            else:
                is_trusted = bool(self.check_pin_trust(environ))
                yield traceback.render_full(
                    evalex=self.evalex, evalex_trusted=is_trusted, secret=self.secret
                ).encode("utf-8", "replace")

            traceback.log(environ["wsgi.errors"])
Пример #32
0
    def error(error):
        if isinstance(error, SQLAlchemyError):
            from litefac.database import db

            db.session.rollback()
        from werkzeug.debug.tbtools import get_current_traceback

        traceback = get_current_traceback(skip=1, show_hidden_frames=False,
                                          ignore_system_exceptions=True)
        app.logger.error("%s %s" % (request.method, request.url))
        app.logger.error(traceback.plaintext)
        sender_email(traceback)
        return render_template("error.html", msg=u"%s %s时,系统异常" % (request.method, request.url),
                               detail=traceback.render_summary(),
                               back_url=request.args.get("back_url", "/"),
                               nav_bar=nav_bar, titlename=u"错误"), 403
Пример #33
0
    def error(error):
        if isinstance(error, SQLAlchemyError):
            db.session.rollback()
        from werkzeug.debug.tbtools import get_current_traceback

        traceback = get_current_traceback(skip=1, show_hidden_frames=False,
                                          ignore_system_exceptions=True)
        app.logger.error("%s %s" % (request.method, request.url))
        app.logger.error(traceback.plaintext)
        email_exception(traceback)
        return render_template('error.html',
                               title=_(u"failed request: %(method)s %(url)s",
                                       method=request.method,
                                       url=request.url),
                               text=traceback.render_summary(),
                               backref=request.args.get('backref', '/'))
Пример #34
0
    def debug_application(self, environ, start_response):
        """Run the application and conserve the traceback frames."""
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item
            if hasattr(app_iter, 'close'):
                app_iter.close()
        except Exception:
            if hasattr(app_iter, 'close'):
                app_iter.close()
            traceback = get_current_traceback(
                skip=1,
                show_hidden_frames=self.show_hidden_frames,
                ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            try:
                start_response(
                    '500 INTERNAL SERVER ERROR',
                    [
                        ('Content-Type', 'text/html; charset=utf-8'),
                        # Disable Chrome's XSS protection, the debug
                        # output can cause false-positives.
                        ('X-XSS-Protection', '0'),
                    ])
            except Exception:
                # if we end up here there has been output but an error
                # occurred.  in that situation we can do nothing fancy any
                # more, better log something into the error log and fall
                # back gracefully.
                environ['wsgi.errors'].write(
                    'Debugging middleware caught exception in streamed '
                    'response at a point where response headers were already '
                    'sent.\n')
            else:
                yield traceback.render_full(evalex=self.evalex,
                                            lodgeit_url=self.lodgeit_url,
                                            secret=self.secret) \
                               .encode('utf-8', 'replace')

            traceback.log(environ['wsgi.errors'])
Пример #35
0
    def error(error):
        if isinstance(error, SQLAlchemyError):
            from lite_mms.database import db

            db.session.rollback()
        from werkzeug.debug.tbtools import get_current_traceback

        traceback = get_current_traceback(skip=1,
                                          show_hidden_frames=False,
                                          ignore_system_exceptions=True)
        app.logger.error("%s %s" % (request.method, request.url))
        app.logger.error(traceback.plaintext)
        sender_email(traceback)
        return redirect(
            url_for("error",
                    errors=u"%s %s时,系统异常" % (request.method, request.url),
                    detail=traceback.render_summary(),
                    url=request.args.get("url", "/")))
Пример #36
0
    def debug_application(self, environ, start_response):
        """Run the application and conserve the traceback frames."""
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item
            if hasattr(app_iter, 'close'):
                app_iter.close()
        except Exception:
            if hasattr(app_iter, 'close'):
                app_iter.close()
            traceback = get_current_traceback(
                skip=1, show_hidden_frames=self.show_hidden_frames,
                ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            try:
                start_response('500 INTERNAL SERVER ERROR', [
                    ('Content-Type', 'text/html; charset=utf-8'),
                    # Disable Chrome's XSS protection, the debug
                    # output can cause false-positives.
                    ('X-XSS-Protection', '0'),
                ])
            except Exception:
                # if we end up here there has been output but an error
                # occurred.  in that situation we can do nothing fancy any
                # more, better log something into the error log and fall
                # back gracefully.
                environ['wsgi.errors'].write(
                    'Debugging middleware caught exception in streamed '
                    'response at a point where response headers were already '
                    'sent.\n')
            else:
                is_trusted = bool(self.check_pin_trust(environ))
                yield traceback.render_full(evalex=self.evalex,
                                            evalex_trusted=is_trusted,
                                            secret=self.secret) \
                    .encode('utf-8', 'replace')

            traceback.log(environ['wsgi.errors'])
Пример #37
0
    def debug_application(self, environ, start_response):
        """Run the application and conserve the traceback frames."""
        app_iter = None
        try:
            app_iter = self.app(environ, start_response)
            for item in app_iter:
                yield item
            if hasattr(app_iter, 'close'):
                app_iter.close()
        except Exception:
            if hasattr(app_iter, 'close'):
                app_iter.close()
            traceback = get_current_traceback(skip=1, show_hidden_frames=
                                              self.show_hidden_frames,
                                              ignore_system_exceptions=True)
            for frame in traceback.frames:
                self.frames[frame.id] = frame
            self.tracebacks[traceback.id] = traceback

            try:
                start_response('500 INTERNAL SERVER ERROR', [
                    ('Content-Type', 'text/html; charset=utf-8')
                ])
            except Exception:
                # if we end up here there has been output but an error
                # occurred.  in that situation we can do nothing fancy any
                # more, better log something into the error log and fall
                # back gracefully.
                environ['wsgi.errors'].write(
                    'Debugging middleware caught exception in streamed '
                    'response at a point where response headers were already '
                    'sent.\n')
            else:
                yield traceback.render_full(evalex=self.evalex,
                                            lodgeit_url=self.lodgeit_url,
                                            secret=self.secret,
                                            pid=self.multiprocess_support and getpid() or '') \
                               .encode('utf-8', 'replace')

            traceback.log(environ['wsgi.errors'])
Пример #38
0
    def wrapper(request, *args, **kwargs):
        try:
            return func(request, *args, **kwargs)

        except api_exceptions.NotFound as ex:
            return responses.NotFound(**_render_error(ex))

        except api_exceptions.Forbidden as ex:
            return responses.Forbidden(**_render_error(ex))

        except api_exceptions.BadRequest as ex:
            return responses.BadRequest(**_render_error(ex))

        except Exception as ex:
            if settings.DEBUG == False:
                return responses.InternalServerError(**_render_error(ex, "Internal error: {}".format(str(ex))))
            else:
                from werkzeug.debug.tbtools import get_current_traceback
                traceback = get_current_traceback()
                return responses.InternalServerError(
                    traceback.plaintext,
                    headers={"Content-type": "text/plain"}
                )
Пример #39
0
    def wrapper(request, *args, **kwargs):
        try:
            return func(request, *args, **kwargs)

        except api_exceptions.NotFound as ex:
            return responses.NotFound(**_render_error(ex))

        except api_exceptions.Forbidden as ex:
            return responses.Forbidden(**_render_error(ex))

        except api_exceptions.BadRequest as ex:
            return responses.BadRequest(**_render_error(ex))

        except Exception as ex:
            if settings.DEBUG == False:
                return responses.InternalServerError(
                    **_render_error(ex, "Internal error: {}".format(str(ex))))
            else:
                from werkzeug.debug.tbtools import get_current_traceback
                traceback = get_current_traceback()
                return responses.InternalServerError(
                    traceback.plaintext,
                    headers={"Content-type": "text/plain"})
Пример #40
0
 def showsyntaxerror(self, filename=None):
     from werkzeug.debug.tbtools import get_current_traceback
     tb = get_current_traceback(skip=4)
     sys.stdout._write(tb.render_summary())
Пример #41
0
    def run_wsgi(self):
        app = self.server.app
        environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                code, msg = status.split(None, 1)
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)

                if 'content-length' not in header_keys:
                    self.close_connection = True
                    self.send_header('Connection', 'close')
                if 'server' not in header_keys:
                    self.send_header('Server', self.version_string())
                if 'date' not in header_keys:
                    self.send_header('Date', self.date_time_string())
                self.end_headers()
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        raise exc_info[0], exc_info[1], exc_info[2]
                finally:
                    exc_info = None

            elif headers_set:
                raise AssertionError('Headers already set')
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)

                if not headers_sent:
                    write('')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(app)
        except (socket.error, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except:
                pass

            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)
Пример #42
0
    def run_wsgi(self):
        # XXX: Copy paste of _WSGIRequestHandler.run_wsgi
        #       cause there is no other way to use metrics on error

        if self.headers.get('Expect', '').lower().strip() == '100-continue':
            self.wfile.write(b'HTTP/1.1 100 Continue\r\n\r\n')

        self.environ = environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            assert headers_set, 'write() before start_response'
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                try:
                    code, msg = status.split(None, 1)
                except ValueError:
                    code, msg = status, ""
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if 'content-length' not in header_keys:
                    self.close_connection = True
                    self.send_header('Connection', 'close')
                if 'server' not in header_keys:
                    self.send_header('Server', self.version_string())
                if 'date' not in header_keys:
                    self.send_header('Date', self.date_time_string())
                self.end_headers()

            assert isinstance(data, bytes), 'applications must write bytes'
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        reraise(*exc_info)
                finally:
                    exc_info = None
            elif headers_set:
                raise AssertionError('Headers already set')
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)
                if not headers_sent:
                    write(b'')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(self.server.app)
        except (socket.error, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except Exception:
            # XXX: all that copy-paste for the sake of this line
            wsgi.exception.enter()

            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except Exception:
                print("EXCEPTION IN EXCEPTION")
                pass
            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)
Пример #43
0
 def showsyntaxerror(self, filename=None):
     from werkzeug.debug.tbtools import get_current_traceback
     tb = get_current_traceback(skip=4)
     sys.stdout._write(tb.render_summary())
Пример #44
0
                if not headers_sent:
                    write('')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(app)
        except (socket.error, socket.timeout), e:
            self.connection_dropped(e, environ)
        except:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except:
                pass
            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)

    def handle(self):
        """Handles a request ignoring dropped connections."""
        try:
            return BaseHTTPRequestHandler.handle(self)
Пример #45
0
Файл: ui.py Проект: temcom/flock
def internal_error(exception):
    app.logger.exception(exception)
    tb = tbtools.get_current_traceback()
    print "traceback", tb
    return flask.render_template('500.html', exception=exception, traceback=tb.plaintext)
Пример #46
0
    def _emit(self, record, **kwargs):
        data = {
            'params': record.args,
            'created': record.created,
        }
        try:
            data['message'] = force_text(record.msg)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            data['message'] = repr(record.msg)[1:-1]

        try:
            data['formatted'] = force_text(record.message)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            data['formatted'] = repr(record.message)[1:-1]

        if record.exc_info and all(record.exc_info):
            # Record all details we can find from the current exception.
            tb = get_current_traceback(skip=1)
            exc = escape(tb.exception)
            serialized_frames = []
            for frame in tb.frames:
                serialized_frame = {
                    'id': frame.id,
                    'filename': escape(frame.filename),
                    'lineno': frame.lineno,
                    'function_name': escape(frame.function_name),
                    'current_line': escape(frame.current_line.strip()),
                    'sourcelines': frame.sourcelines,
                    'lines': []
                }

                for line in frame.get_annotated_lines():
                    serialized_frame['lines'].append({
                        'classes': line.classes,
                        'lineno': line.lineno,
                        'code': escape(line.code)
                    })

                serialized_frames.append(serialized_frame)

            data['traceback'] = {
                'title': exc,
                'exception': exc,
                'exception_type': escape(tb.exception_type),
                'frames': serialized_frames,
                'plaintext': tb.plaintext,
                'traceback_id': tb.id,
            }

        data['level'] = record.levelno
        data['logger'] = record.name

        if hasattr(record, 'tags'):
            data['tags'] = record.tags

        if hasattr(record, 'extra'):
            data['extra'] = record.extra

        endpoint = self.host + reverse('api-v1:message')
        headers = {'content-type': 'application/json'}

        # TODO: error handling.
        requests.post(endpoint, data=json.dumps(data), headers=headers)
Пример #47
0
    def run_wsgi(self):
        app = self.server.app
        environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                code, msg = status.split(None, 1)
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)

                if 'content-length' not in header_keys:
                    self.close_connection = True
                    self.send_header('Connection', 'close')
                if 'server' not in header_keys:
                    self.send_header('Server', self.version_string())
                if 'date' not in header_keys:
                    self.send_header('Date', self.date_time_string())
                self.end_headers()
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info = None):
            if exc_info:
                try:
                    if headers_sent:
                        raise exc_info[0], exc_info[1], exc_info[2]
                finally:
                    exc_info = None

            elif headers_set:
                raise AssertionError('Headers already set')
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)

                if not headers_sent:
                    write('')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(app)
        except (socket.error, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except:
                pass

            self.server.log('error', 'Error on request:\n%s', traceback.plaintext)
Пример #48
0
                if not headers_sent:
                    write('')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(app)
        except (socket.error, socket.timeout), e:
            self.connection_dropped(e, environ)
        except:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except:
                pass
            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)

    def connection_dropped(self, error, environ):
        """Called if the connection was closed by the client.  By default
        nothing happens.
        """
    def _post_data(self, context=None, traceback=None):
        """POST data to the the Exceptional API. If DEBUG is True then data is
        sent to ``EXCEPTIONAL_DEBUG_URL`` if it has been defined. If TESTING is
        true, error data is stored in the global ``flask.g.exceptional``
        variable.

        :param context: Default ``None``. The current application context.
        :param traceback: Default ``None``. The exception stack trace.
        """
        app = context.app if context else stack.top.app
        application_data = self.__get_application_data(app)
        client_data = {
            "name": "flask-exceptional",
            "version": self.__version__,
            "protocol_version": self.__protocol_version
        }

        if context:
            request_data = self.__get_request_data(app, context.request,
                    context.session)
            context_data = getattr(context, "exceptional_context", None)
        else:
            request_data = None
            context_data = None

        traceback = traceback or tbtools.get_current_traceback()
        exception_data = self.__get_exception_data(traceback)
        encode_basestring = json.encoder.encode_basestring

        def _encode_basestring(value):
            if isinstance(value, str) and \
                    json.encoder.HAS_UTF8.search(value) is not None:
                value = value.decode("utf-8",
                        "replace")  # ensure the decode succeeds.

            replace = lambda match: json.encoder.ESCAPE_DCT[match.group(0)]

            return u'"%s"' % json.encoder.ESCAPE.sub(replace, value)

        try:
            json.encoder.encode_basestring = _encode_basestring
            error_data = json.dumps({
                "application_environment": application_data,
                "client": client_data,
                "request": request_data,
                "exception": exception_data,
                "context": context_data
            }, ensure_ascii=False).encode("utf-8")
        finally:
            json.encoder.encode_basestring = encode_basestring

        if app.testing:
            g.exceptional = error_data

        if self.url:
            request = Request(self.url)
            request.add_header("Content-Type", "application/json")

            if app.debug:
                data = error_data
            else:
                request.add_header("Content-Encoding", "deflate")
                data = compress(error_data, 1)

            try:
                try:
                    urlopen(request, data)
                except HTTPError, e:
                    if e.code >= 400:
                        raise
            except URLError:
                message = "Unable to connect to %s. See http://status.exceptional.io for details. Error data:\n%s"  # NOQA
                app.logger.warning(message, self.url, error_data,
                        exc_info=True)
            except BadStatusLine:
                pass
Пример #50
0
    def run_wsgi(self):
        environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            assert headers_set, 'write() before start_response'
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                try:
                    code, msg = status.split(None, 1)
                except ValueError:
                    code, msg = status, ""
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if 'content-length' not in header_keys:
                    self.close_connection = True
                    self.send_header('Connection', 'close')
                if 'server' not in header_keys:
                    self.send_header('Server', self.version_string())
                if 'date' not in header_keys:
                    self.send_header('Date', self.date_time_string())
                self.end_headers()

            assert type(data) is bytes, 'applications must write bytes'
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        reraise(*exc_info)
                finally:
                    exc_info = None
            elif headers_set:
                raise AssertionError('Headers already set')
            headers_set[:] = [status, response_headers]
            return write

        def app_proxy(environ, start_response):
            # We reject an invalid content length here because it can cause
            # problems with how WSGI apps respond to values in it.
            content_length = environ['CONTENT_LENGTH']
            if content_length and not content_length.isdigit():
                resp = BadRequest()
            else:
                resp = self.server.app
            return resp(environ, start_response)

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)
                if not headers_sent:
                    write(b'')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(app_proxy)
        except (socket.error, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except Exception:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except Exception:
                pass
            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)
Пример #51
0
    def run_wsgi(self):
        if self.headers.get("Expect", "").lower().strip() == "100-continue":
            self.wfile.write(b"HTTP/1.1 100 Continue\r\n\r\n")

        environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            assert headers_set, "write() before start_response"
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                try:
                    code, msg = status.split(None, 1)
                except ValueError:
                    code, msg = status, ""
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if "content-length" not in header_keys:
                    self.close_connection = True
                    self.send_header("Connection", "close")
                if "server" not in header_keys:
                    self.send_header("Server", self.version_string())
                if "date" not in header_keys:
                    self.send_header("Date", self.date_time_string())
                self.end_headers()

            assert type(data) is bytes, "applications must write bytes"
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        reraise(*exc_info)
                finally:
                    exc_info = None
            elif headers_set:
                raise AssertionError("Headers already set")
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)
                if not headers_sent:
                    write(b"")
            finally:
                if hasattr(application_iter, "close"):
                    application_iter.close()
                application_iter = None

        try:
            execute(self.server.app)
        except (socket.error, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except Exception:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback

            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except Exception:
                pass
            self.server.log("error", "Error on request:\n%s", traceback.plaintext)
Пример #52
0
 def _store_traceback(self):
     traceback = get_current_traceback(skip=1,
                                       show_hidden_frames=False,
                                       ignore_system_exceptions=True)
     self.tracebacks[traceback.id] = traceback
     return "/debug/{}".format(traceback.id)
Пример #53
0
 def showtraceback(self):
     from werkzeug.debug.tbtools import get_current_traceback
     tb = get_current_traceback(skip=1)
     sys.stdout._write(tb.render_summary())
Пример #54
0
    def run_wsgi(self):
        if self.headers.get("Expect", "").lower().strip() == "100-continue":
            self.wfile.write(b"HTTP/1.1 100 Continue\r\n\r\n")

        self.environ = environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            assert headers_set, "write() before start_response"
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                try:
                    code, msg = status.split(None, 1)
                except ValueError:
                    code, msg = status, ""
                code = int(code)
                self.log_request(code, data.__len__())
                self.send_response(code, msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if not (
                    "content-length" in header_keys
                    or environ["REQUEST_METHOD"] == "HEAD"
                    or code < 200
                    or code in (204, 304)
                ):
                    self.close_connection = True
                    self.send_header("Connection", "close")
                if "server" not in header_keys:
                    self.send_header("Server", self.version_string())
                if "date" not in header_keys:
                    self.send_header("Date", self.date_time_string())
                self.end_headers()

            assert isinstance(data, bytes), "applications must write bytes"
            if data:
                # Only write data if there is any to avoid Python 3.5 SSL bug
                self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        reraise(*exc_info)
                finally:
                    exc_info = None
            elif headers_set:
                raise AssertionError("Headers already set")
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)
                if not headers_sent:
                    write(b"")
            finally:
                if hasattr(application_iter, "close"):
                    application_iter.close()

        try:
            execute(self.server.app)
        except (ConnectionError, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except Exception:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback

            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except Exception:
                pass
            self.server.log("error", "Error on request:\n%s", traceback.plaintext)
Пример #55
0
    def run_wsgi(self):
        if self.headers.get('Expect', '').lower().strip() == '100-continue':
            self.wfile.write(b'HTTP/1.1 100 Continue\r\n\r\n')

        self.environ = environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            assert headers_set, 'write() before start_response'
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                try:
                    code, msg = status.split(None, 1)
                except ValueError:
                    code, msg = status, ""
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if 'content-length' not in header_keys:
                    self.close_connection = True
                    self.send_header('Connection', 'close')
                if 'server' not in header_keys:
                    self.send_header('Server', self.version_string())
                if 'date' not in header_keys:
                    self.send_header('Date', self.date_time_string())
                self.end_headers()

            assert isinstance(data, bytes), 'applications must write bytes'
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        reraise(*exc_info)
                finally:
                    exc_info = None
            elif headers_set:
                raise AssertionError('Headers already set')
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)
                if not headers_sent:
                    write(b'')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(self.server.app)
        except (socket.error, socket.timeout) as e:
            self.connection_dropped(e, environ)
        except Exception:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except Exception:
                pass
            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)
Пример #56
0
 def showtraceback(self):
     from werkzeug.debug.tbtools import get_current_traceback
     tb = get_current_traceback(skip=1)
     sys.stdout._write(tb.render_summary())
Пример #57
0
class WSGIRequestHandler(BaseHTTPRequestHandler, object):
    """A request handler that implements WSGI dispatching."""

    @property
    def server_version(self):
        return 'Werkzeug/' + werkzeug.__version__

    def make_environ(self):
        request_url = _safe_urlsplit(self.path)

        def shutdown_server():
            self.server.shutdown_signal = True

        url_scheme = self.server.ssl_context is None and 'http' or 'https'
        environ = {
            'wsgi.version':         (1, 0),
            'wsgi.url_scheme':      url_scheme,
            'wsgi.input':           self.rfile,
            'wsgi.errors':          sys.stderr,
            'wsgi.multithread':     self.server.multithread,
            'wsgi.multiprocess':    self.server.multiprocess,
            'wsgi.run_once':        False,
            'werkzeug.server.shutdown':
                                    shutdown_server,
            'SERVER_SOFTWARE':      self.server_version,
            'REQUEST_METHOD':       self.command,
            'SCRIPT_NAME':          '',
            'PATH_INFO':            unquote(request_url.path),
            'QUERY_STRING':         request_url.query,
            'CONTENT_TYPE':         self.headers.get('Content-Type', ''),
            'CONTENT_LENGTH':       self.headers.get('Content-Length', ''),
            'REMOTE_ADDR':          self.client_address[0],
            'REMOTE_PORT':          self.client_address[1],
            'SERVER_NAME':          self.server.server_address[0],
            'SERVER_PORT':          str(self.server.server_address[1]),
            'SERVER_PROTOCOL':      self.request_version
        }

        for key, value in self.headers.items():
            key = 'HTTP_' + key.upper().replace('-', '_')
            if key not in ('HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH'):
                environ[key] = value

        if request_url.netloc:
            environ['HTTP_HOST'] = request_url.netloc

        return environ

    def run_wsgi(self):
        app = self.server.app
        environ = self.make_environ()
        headers_set = []
        headers_sent = []

        def write(data):
            assert headers_set, 'write() before start_response'
            if not headers_sent:
                status, response_headers = headers_sent[:] = headers_set
                code, msg = status.split(None, 1)
                self.send_response(int(code), msg)
                header_keys = set()
                for key, value in response_headers:
                    self.send_header(key, value)
                    key = key.lower()
                    header_keys.add(key)
                if 'content-length' not in header_keys:
                    self.close_connection = True
                    self.send_header('Connection', 'close')
                if 'server' not in header_keys:
                    self.send_header('Server', self.version_string())
                if 'date' not in header_keys:
                    self.send_header('Date', self.date_time_string())
                self.end_headers()

            assert type(data) is str, 'applications must write bytes'
            self.wfile.write(data)
            self.wfile.flush()

        def start_response(status, response_headers, exc_info=None):
            if exc_info:
                try:
                    if headers_sent:
                        raise exc_info[0], exc_info[1], exc_info[2]
                finally:
                    exc_info = None
            elif headers_set:
                raise AssertionError('Headers already set')
            headers_set[:] = [status, response_headers]
            return write

        def execute(app):
            application_iter = app(environ, start_response)
            try:
                for data in application_iter:
                    write(data)
                # make sure the headers are sent
                if not headers_sent:
                    write('')
            finally:
                if hasattr(application_iter, 'close'):
                    application_iter.close()
                application_iter = None

        try:
            execute(app)
        except (socket.error, socket.timeout), e:
            self.connection_dropped(e, environ)
        except Exception:
            if self.server.passthrough_errors:
                raise
            from werkzeug.debug.tbtools import get_current_traceback
            traceback = get_current_traceback(ignore_system_exceptions=True)
            try:
                # if we haven't yet sent the headers but they are set
                # we roll back to be able to set them again.
                if not headers_sent:
                    del headers_set[:]
                execute(InternalServerError())
            except Exception:
                pass
            self.server.log('error', 'Error on request:\n%s',
                            traceback.plaintext)
Пример #58
0
    def _post_data(self, context, traceback=None):
        """POST data to the the Exceptional API. If DEBUG is True then data is
        sent to ``EXCEPTIONAL_DEBUG_URL`` if it has been defined. If TESTING is
        true, error data is stored in the global ``flask.g.exceptional``
        variable.

        :param context: The current application or application context.
        :param traceback: Default ``None``. The exception stack trace.
        """
        if context:
            if isinstance(context, Flask):
                app = context
                context = None
            else:
                app = context.app
        else:
            app = stack.top.app

        application_data = self.__get_application_data(app)
        client_data = {
            "name": "flask-exceptional",
            "version": self.__version__,
            "protocol_version": self.__protocol_version
        }

        if context:
            request_data = self.__get_request_data(app, context.request,
                                                   context.session)
            context_data = getattr(context, "exceptional_context", None)
        else:
            request_data = None
            context_data = None

        traceback = traceback or tbtools.get_current_traceback()
        exception_data = self.__get_exception_data(traceback)
        encode_basestring = json.encoder.encode_basestring

        def _encode_basestring(value):
            if isinstance(value, str) and \
                    json.encoder.HAS_UTF8.search(value) is not None:
                value = value.decode("utf-8",
                                     "replace")  # ensure the decode succeeds.

            replace = lambda match: json.encoder.ESCAPE_DCT[match.group(0)]

            return u'"%s"' % json.encoder.ESCAPE.sub(replace, value)

        try:
            json.encoder.encode_basestring = _encode_basestring
            ret_val = json.dumps(
                {
                    "application_environment": application_data,
                    "client": client_data,
                    "request": request_data,
                    "exception": exception_data,
                    "context": context_data
                },
                ensure_ascii=False).encode("utf-8")
        finally:
            json.encoder.encode_basestring = encode_basestring

        if context and app.testing:
            g.exceptional = ret_val

        if self.url:
            request = Request(self.url)
            request.add_header("Content-Type", "application/json")

            if app.debug:
                data = ret_val
            else:
                request.add_header("Content-Encoding", "deflate")
                data = compress(ret_val, 1)

            try:
                try:
                    urlopen(request, data)
                except HTTPError, e:
                    if e.code >= 400:
                        raise
            except URLError:
                message = "Unable to connect to %s. See http://status.exceptional.io for details. Error data:\n%s"  # NOQA
                app.logger.warning(message, self.url, ret_val, exc_info=True)
            except BadStatusLine:
                pass

        return ret_val