Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/sentry/api/serializers/models/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def serialize(self, obj, attrs, user):
feature_list.append('sso')
if features.has('organizations:callsigns', obj, actor=user):
feature_list.append('callsigns')
if features.has('organizations:new-tracebacks', obj, actor=user):
feature_list.append('new-tracebacks')
if features.has('organizations:onboarding', obj, actor=user) and \
not OrganizationOption.objects.filter(organization=obj).exists():
feature_list.append('onboarding')
Expand Down
1 change: 1 addition & 0 deletions src/sentry/conf/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ def create_partitioned_queues(name):
'organizations:create': True,
'organizations:sso': True,
'organizations:callsigns': False,
'organizations:new-tracebacks': False,
'projects:global-events': False,
'projects:quotas': True,
'projects:plugins': True,
Expand Down
1 change: 1 addition & 0 deletions src/sentry/features/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
default_manager.add('organizations:sso', OrganizationFeature)
default_manager.add('organizations:onboarding', OrganizationFeature)
default_manager.add('organizations:callsigns', OrganizationFeature)
default_manager.add('organizations:new-tracebacks', OrganizationFeature)
default_manager.add('projects:global-events', ProjectFeature)
default_manager.add('projects:quotas', ProjectFeature)
default_manager.add('projects:plugins', ProjectPluginFeature)
Expand Down
2 changes: 1 addition & 1 deletion src/sentry/interfaces/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Message(Interface):
>>> }
"""
score = 0
display_score = 1050
display_score = 2050

@classmethod
def to_python(cls, data):
Expand Down
4 changes: 3 additions & 1 deletion src/sentry/static/sentry/app/components/clippedBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ const ClippedBox = React.createClass({
}
},

reveal() {
reveal(e) {
e.stopPropagation();

this.setState({
clipped: false
});
Expand Down
97 changes: 42 additions & 55 deletions src/sentry/static/sentry/app/components/events/interfaces/frame.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import _ from 'underscore';
import classNames from 'classnames';
import {defined, objectIsEmpty, isUrl} from '../../../utils';

import ClippedBox from '../../../components/clippedBox';
import TooltipMixin from '../../../mixins/tooltip';
import FrameVariables from './frameVariables';
import ContextLine from './contextLine';
import StrictClick from '../../strictClick';
import Truncate from '../../../components/truncate';
import {t} from '../../../locale';
import {defined, objectIsEmpty, isUrl} from '../../../utils';

import ContextLine from './contextLine';
import FrameVariables from './frameVariables';

function trimPackage(pkg) {
let pieces = pkg.split(/\//g);
Expand All @@ -33,17 +36,27 @@ const Frame = React.createClass({
})
],

getDefaultProps() {
return {
isExpanded: false
};
},

getInitialState() {
// isExpanded can be initialized to true via parent component;
// data synchronization is not important
// https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html
return {
isExpanded: defined(this.props.isExpanded) ? this.props.isExpanded : false
isExpanded: this.props.isExpanded
};
},

toggleContext(evt) {
evt && evt.preventDefault();
if (!this.isExpandable()) {
return null;
}

this.setState({
isExpanded: !this.state.isExpanded
});
Expand All @@ -53,19 +66,14 @@ const Frame = React.createClass({
return defined(this.props.data.context) && this.props.data.context.length;
},

hasExtendedSource() {
return this.hasContextSource() && this.props.data.context.length > 1;
},

hasContextVars() {
return !objectIsEmpty(this.props.data.vars);
},

isExpandable() {
return this.hasExtendedSource() || this.hasContextVars();
return this.hasContextSource() || this.hasContextVars();
},


renderOriginalSourceInfo() {
let data = this.props.data;

Expand Down Expand Up @@ -94,7 +102,11 @@ const Frame = React.createClass({
// lazy to change this up right now. This should be a format string

if (defined(data.filename || data.module)) {
title.push(<code key="filename">{data.filename || data.module}</code>);
title.push((
<code key="filename" className="filename">
<Truncate value={data.filename || data.module} maxLength={100} leftTrim={true} />
</code>
));
if (isUrl(data.absPath)) {
title.push(<a href={data.absPath} className="icon-open" key="share" target="_blank" />);
}
Expand All @@ -104,26 +116,26 @@ const Frame = React.createClass({
}

if (defined(data.function)) {
title.push(<code key="function">{data.function}</code>);
title.push(<code key="function" className="function">{data.function}</code>);
}

// we don't want to render out zero line numbers which are used to
// indicate lack of source information for native setups. We could
// TODO(mitsuhiko): only do this for events from native platforms?
if (defined(data.lineNo) && data.lineNo != 0) {
else if (defined(data.lineNo) && data.lineNo != 0) {
// TODO(dcramer): we need to implement source mappings
// title.push(<span className="pull-right blame"><a><span className="icon-mark-github"></span> View Code</a></span>);
title.push(<span className="in-at" key="at"> {t('at line')} </span>);
if (defined(data.colNo)) {
title.push(<code key="line">{data.lineNo}:{data.colNo}</code>);
title.push(<code key="line" className="lineno">{data.lineNo}:{data.colNo}</code>);
} else {
title.push(<code key="line">{data.lineNo}</code>);
title.push(<code key="line" className="lineno">{data.lineNo}</code>);
}
}

if (defined(data.package)) {
title.push(<span className="within" key="within"> {t('within')} </span>);
title.push(<code title={data.package}>{trimPackage(data.package)}</code>);
title.push(<code title={data.package} className="package">{trimPackage(data.package)}</code>);
}

if (defined(data.origAbsPath)) {
Expand All @@ -134,35 +146,9 @@ const Frame = React.createClass({
);
}

if (data.inApp) {
title.push(<span key="in-app"><span className="divider"/>{t('application')}</span>);
}
return title;
},

renderContextLine(line, activeLineNo) {
let liClassName = 'expandable';
if (line[0] === activeLineNo) {
liClassName += ' active';
}

let lineWs;
let lineCode;
if (defined(line[1]) && line[1].match) {
[, lineWs, lineCode] = line[1].match(/^(\s*)(.*?)$/m);
} else {
lineWs = '';
lineCode = '';
}
return (
<li className={liClassName} key={line[0]}>
<span className="ws">{
lineWs}</span><span className="contextline">{lineCode
}</span>
</li>
);
},

renderContext() {
let data = this.props.data;
let context = '';
Expand Down Expand Up @@ -192,11 +178,11 @@ const Frame = React.createClass({
}

{data.context && contextLines.map((line, index) => {
return <ContextLine key={index} line={line} isActive={data.lineNo === line[0]}/>;
return <ContextLine key={index} line={line} isActive={data.lineNo === line[0]} />;
})}

{hasContextVars &&
<FrameVariables data={data.vars} key="vars" />
<ClippedBox clipHeight={100}><FrameVariables data={data.vars} key="vars" /></ClippedBox>
}
</ol>
</StrictClick>
Expand All @@ -221,7 +207,7 @@ const Frame = React.createClass({

renderDefaultLine() {
return (
<p>
<p onClick={this.toggleContext}>
{this.renderDefaultTitle()}
{this.renderExpander()}
</p>
Expand All @@ -230,31 +216,30 @@ const Frame = React.createClass({

renderCocoaLine() {
let data = this.props.data;
let className = 'stacktrace-table';
return (
<div className={className}>
<p className="as-table" onClick={this.toggleContext}>
{defined(data.package)
? (
<div className="trace-col package" title={data.package}>
<span className="package" title={data.package}>
{trimPackage(data.package)}
</div>
</span>
) : (
<div className="trace-col package"/>
<span className="package"/>
)
}
<div className="trace-col address">
<span className="address">
{data.instructionAddr}
</div>
<div className="trace-col symbol">
</span>
<span className="symbol">
<code>{data.function || '<unknown>'}</code>
{data.instructionOffset &&
<span className="offset">{' + ' + data.instructionOffset}</span>}
{data.filename &&
<span className="filename">{data.filename}
{data.lineNo ? ':' + data.lineNo : ''}</span>}
{this.renderExpander()}
</div>
</div>
</span>
</p>
);
},

Expand All @@ -273,6 +258,8 @@ const Frame = React.createClass({

let className = classNames({
'frame': true,
'is-expandable': this.isExpandable(),
'expanded': this.state.isExpanded,
'system-frame': !data.inApp,
'frame-errors': data.errors,
'leads-to-app': !data.inApp && this.props.nextFrameInApp
Expand Down
Loading