Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Intellij Community
Commits
eb5bac74
Commit
eb5bac74
authored
6 years ago
by
Roman Vasiliev
Browse files
Options
Download
Plain Diff
Merge branch 'rvasiliev/error-reporting'
parents
45da7c3f
3652c7bb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java
+18
-0
...orm-impl/src/com/intellij/diagnostic/AbstractMessage.java
platform/platform-impl/src/com/intellij/diagnostic/Developer.java
+11
-0
.../platform-impl/src/com/intellij/diagnostic/Developer.java
platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt
+48
-12
...pl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt
platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java
+5
-1
...m/platform-impl/src/com/intellij/diagnostic/ITNProxy.java
platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
+50
-19
...orm-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
with
132 additions
and
32 deletions
+132
-32
platform/platform-impl/src/com/intellij/diagnostic/AbstractMessage.java
+
18
-
0
View file @
eb5bac74
...
...
@@ -20,6 +20,8 @@ public abstract class AbstractMessage {
private
SubmittedReportInfo
mySubmissionInfo
;
private
String
myAdditionalInfo
;
private
Integer
myAssigneeId
;
private
boolean
myAssigneeVisible
;
private
Long
myDevelopersTimestamp
;
public
abstract
@NotNull
Throwable
getThrowable
();
public
abstract
@NotNull
String
getThrowableText
();
...
...
@@ -96,6 +98,22 @@ public abstract class AbstractMessage {
myAssigneeId
=
assigneeId
;
}
boolean
isAssigneeVisible
()
{
return
myAssigneeVisible
;
}
void
setAssigneeVisible
(
boolean
assigneeVisible
)
{
myAssigneeVisible
=
assigneeVisible
;
}
public
@Nullable
Long
getDevelopersTimestamp
()
{
return
myDevelopersTimestamp
;
}
public
void
setDevelopersTimestamp
(
@Nullable
Long
developersTimestamp
)
{
myDevelopersTimestamp
=
developersTimestamp
;
}
/** @deprecated use {@link #getIncludedAttachments()} instead (to be removed in IDEA 2020) */
@Deprecated
public
List
<
Attachment
>
getAttachments
()
{
...
...
This diff is collapsed.
Click to expand it.
platform/platform-impl/src/com/intellij/diagnostic/Developer.java
+
11
-
0
View file @
eb5bac74
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package
com.intellij.diagnostic
;
import
com.intellij.util.xmlb.annotations.Attribute
;
import
com.intellij.util.xmlb.annotations.Tag
;
import
org.jetbrains.annotations.Nullable
;
@Tag
(
"developer"
)
public
class
Developer
{
public
static
final
Developer
NULL
=
new
Developer
(-
1
,
"<none>"
);
@Attribute
(
"id"
)
private
final
int
myId
;
@Attribute
(
"name"
)
private
final
String
myName
;
@SuppressWarnings
(
"unused"
)
// need for xml serialization
private
Developer
()
{
this
(
0
,
""
);
}
public
Developer
(
int
id
,
String
name
)
{
myId
=
id
;
myName
=
name
;
...
...
This diff is collapsed.
Click to expand it.
platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.kt
+
48
-
12
View file @
eb5bac74
...
...
@@ -5,33 +5,69 @@ import com.intellij.credentialStore.CredentialAttributes
import
com.intellij.credentialStore.Credentials
import
com.intellij.credentialStore.SERVICE_NAME_PREFIX
import
com.intellij.ide.passwordSafe.PasswordSafe
import
com.intellij.openapi.components.PersistentStateComponent
import
com.intellij.openapi.components.RoamingType
import
com.intellij.openapi.components.State
import
com.intellij.openapi.components.Storage
import
com.intellij.openapi.components.*
import
com.intellij.util.io.decodeBase64
import
com.intellij.util.xmlb.XmlSerializer
import
org.jdom.Element
@State
(
name
=
"ErrorReportConfigurable"
,
storages
=
[
(
Storage
(
value
=
"other.xml"
,
deprecated
=
true
,
roamingType
=
RoamingType
.
DISABLED
))])
internal
class
ErrorReportConfigurable
:
PersistentStateComponent
<
OldState
>
{
@State
(
name
=
"ErrorReportConfigurable"
,
storages
=
[
Storage
(
value
=
"other.xml"
,
deprecated
=
true
,
roamingType
=
RoamingType
.
DISABLED
)
,
Storage
(
value
=
"errorReporting.xml"
)])
internal
class
ErrorReportConfigurable
:
PersistentStateComponent
<
Element
>
{
companion
object
{
@JvmStatic
val
SERVICE_NAME
=
"$SERVICE_NAME_PREFIX — JetBrains Account"
@JvmStatic
val
instance
:
ErrorReportConfigurable
get
()
=
ServiceManager
.
getService
(
ErrorReportConfigurable
::
class
.
java
)
@JvmStatic
fun
getCredentials
()
=
PasswordSafe
.
instance
.
get
(
CredentialAttributes
(
SERVICE_NAME
))
}
override
fun
getState
()
=
OldState
()
private
var
myState
:
State
?
=
null
var
developer
:
Developers
?
get
()
=
myState
?.
let
{
Developers
(
it
.
developers
.
toList
(),
it
.
timestamp
)
}
set
(
value
)
{
myState
=
value
?.
let
{
State
(
it
.
developers
.
toList
(),
it
.
timestamp
)
}
}
override
fun
getState
():
Element
?
{
return
myState
?.
let
{
XmlSerializer
.
serialize
(
it
)
}
}
override
fun
loadState
(
element
:
Element
)
{
loadOldState
(
element
)
myState
=
XmlSerializer
.
deserialize
(
element
,
State
::
class
.
java
)
}
private
fun
loadOldState
(
element
:
Element
)
{
val
state
=
XmlSerializer
.
deserialize
(
element
,
OldState
::
class
.
java
)
override
fun
loadState
(
state
:
OldState
)
{
if
(!
state
.
ITN_LOGIN
.
isNullOrEmpty
()
||
!
state
.
ITN_PASSWORD_CRYPT
.
isNullOrEmpty
())
{
PasswordSafe
.
instance
.
set
(
CredentialAttributes
(
SERVICE_NAME
,
state
.
ITN_LOGIN
),
Credentials
(
state
.
ITN_LOGIN
,
state
.
ITN_PASSWORD_CRYPT
!!
.
decodeBase64
()))
}
}
private
data class
State
(
var
developers
:
List
<
Developer
>,
var
timestamp
:
Long
)
{
@Suppress
(
"unused"
)
private
constructor
():
this
(
emptyList
(),
0
)
// need for xml serialization
}
@Suppress
(
"PropertyName"
)
private
class
OldState
{
var
ITN_LOGIN
:
String
?
=
null
var
ITN_PASSWORD_CRYPT
:
String
?
=
null
}
}
@Suppress
(
"PropertyName"
)
internal
class
OldState
{
var
ITN_LOGIN
:
String
?
=
null
var
ITN_PASSWORD_CRYPT
:
String
?
=
null
internal
data class
Developers
(
val
developers
:
List
<
Developer
>,
val
timestamp
:
Long
)
{
companion
object
{
private
const
val
UPDATE_INTERVAL
=
24L
*
60
*
60
*
1000
// 24 hours
}
fun
isUpToDateAt
(
timestamp
:
Long
):
Boolean
{
return
(
timestamp
-
this
.
timestamp
<
UPDATE_INTERVAL
)
&&
developers
.
isNotEmpty
()
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
platform/platform-impl/src/com/intellij/diagnostic/ITNProxy.java
+
5
-
1
View file @
eb5bac74
...
...
@@ -61,7 +61,7 @@ class ITNProxy {
private
static
final
NotNullLazyValue
<
Map
<
String
,
String
>>
TEMPLATE
=
AtomicNotNullLazyValue
.
createValue
(()
->
{
Map
<
String
,
String
>
template
=
new
LinkedHashMap
<>();
template
.
put
(
"protocol.version"
,
"1"
);
template
.
put
(
"protocol.version"
,
"1
.1
"
);
template
.
put
(
"os.name"
,
SystemInfo
.
OS_NAME
);
template
.
put
(
"java.version"
,
SystemInfo
.
JAVA_VERSION
);
template
.
put
(
"java.vm.vendor"
,
SystemInfo
.
JAVA_VENDOR
);
...
...
@@ -254,6 +254,10 @@ class ITNProxy {
if
(
messageObj
.
getAssigneeId
()
!=
null
)
{
append
(
builder
,
"assignee.id"
,
Integer
.
toString
(
messageObj
.
getAssigneeId
()));
}
append
(
builder
,
"assignee.list.visible"
,
Boolean
.
toString
(
messageObj
.
isAssigneeVisible
()));
if
(
messageObj
.
getDevelopersTimestamp
()
!=
null
)
{
append
(
builder
,
"assignee.list.timestamp"
,
Long
.
toString
(
messageObj
.
getDevelopersTimestamp
()));
}
}
return
builder
.
toString
().
getBytes
(
StandardCharsets
.
UTF_8
);
...
...
This diff is collapsed.
Click to expand it.
platform/platform-impl/src/com/intellij/diagnostic/IdeErrorsDialog.java
+
50
-
19
View file @
eb5bac74
...
...
@@ -30,7 +30,6 @@ import com.intellij.openapi.ui.ComboBox;
import
com.intellij.openapi.ui.DialogWrapper
;
import
com.intellij.openapi.ui.Messages
;
import
com.intellij.openapi.util.Comparing
;
import
com.intellij.openapi.util.Condition
;
import
com.intellij.openapi.util.Pair
;
import
com.intellij.openapi.util.Ref
;
import
com.intellij.openapi.util.text.StringUtil
;
...
...
@@ -74,15 +73,15 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
private
static
final
String
ACCEPTED_NOTICES_KEY
=
"exception.accepted.notices"
;
private
static
final
String
ACCEPTED_NOTICES_SEPARATOR
=
":"
;
private
static
final
String
DISABLE_PLUGIN_URL
=
"#disable"
;
private
static
List
<
Developer
>
ourDevelopersList
=
Collections
.
emptyList
();
private
static
final
String
EA_PLUGIN_ID
=
"com.intellij.sisyphus"
;
private
final
MessagePool
myMessagePool
;
private
final
Project
myProject
;
private
final
boolean
my
InternalMod
e
;
private
final
boolean
my
AssigneeVisibl
e
;
private
final
Set
<
String
>
myAcceptedNotices
;
private
final
List
<
MessageCluster
>
myMessageClusters
=
new
ArrayList
<>();
// exceptions with the same stacktrace
private
int
myIndex
,
myLastIndex
=
-
1
;
private
Long
myDevelopersTimestamp
;
private
JLabel
myCountLabel
;
private
JTextComponent
myInfoLabel
;
...
...
@@ -101,14 +100,14 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
super
(
project
,
true
);
myMessagePool
=
messagePool
;
myProject
=
project
;
my
InternalMod
e
=
ApplicationManager
.
getApplication
().
isInternal
();
my
AssigneeVisibl
e
=
ApplicationManager
.
getApplication
().
isInternal
()
||
PluginManager
.
isPluginInstalled
(
PluginId
.
getId
(
EA_PLUGIN_ID
))
;
setTitle
(
DiagnosticBundle
.
message
(
"error.list.title"
));
setModal
(
false
);
init
();
setCancelButtonText
(
CommonBundle
.
message
(
"close.action.name"
));
if
(
my
InternalMod
e
)
{
if
(
my
AssigneeVisibl
e
)
{
loadDevelopersList
();
}
...
...
@@ -123,30 +122,45 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
}
private
void
loadDevelopersList
()
{
if
(!
ourDevelopersList
.
isEmpty
())
{
myAssigneeCombo
.
setModel
(
new
CollectionComboBoxModel
<>(
ourDevelopersList
));
ErrorReportConfigurable
configurable
=
ErrorReportConfigurable
.
getInstance
();
Developers
developers
=
configurable
.
getDeveloper
();
if
(
developers
!=
null
&&
developers
.
isUpToDateAt
(
System
.
currentTimeMillis
()))
{
setDevelopers
(
developers
);
}
else
{
new
Task
.
Backgroundable
(
null
,
"Loading Developers List"
,
true
)
{
@Override
public
void
run
(
@NotNull
ProgressIndicator
indicator
)
{
try
{
List
<
Developer
>
developers
=
ITNProxy
.
fetchDevelopers
(
indicator
);
//noinspection AssignmentToStaticFieldFromInstanceMethod
ourDevelopersList
=
developers
;
Developers
updatedDevelopers
=
new
Developers
(
ITNProxy
.
fetchDevelopers
(
indicator
),
System
.
currentTimeMillis
());
UIUtil
.
invokeLaterIfNeeded
(()
->
{
configurable
.
setDeveloper
(
updatedDevelopers
);
if
(
isShowing
())
{
myAssigneeCombo
.
setModel
(
new
CollectionComboBoxModel
<>(
developers
));
setDevelopers
(
updatedDevelopers
);
}
});
}
catch
(
UnknownHostException
e
)
{
LOG
.
debug
(
e
);
UIUtil
.
invokeLaterIfNeeded
(()
->
{
if
(
isShowing
())
{
setDevelopers
(
developers
);
}
});
}
catch
(
UnknownHostException
e
)
{
LOG
.
debug
(
e
);
}
catch
(
IOException
e
)
{
LOG
.
warn
(
e
);
}
}
}.
queue
();
}
}
private
void
setDevelopers
(
@Nullable
Developers
developers
)
{
if
(
developers
!=
null
)
{
myAssigneeCombo
.
setModel
(
new
CollectionComboBoxModel
<>(
developers
.
getDevelopers
()));
myDevelopersTimestamp
=
developers
.
getTimestamp
();
}
}
private
int
selectMessage
(
@Nullable
LogMessage
defaultMessage
)
{
if
(
defaultMessage
!=
null
)
{
for
(
int
i
=
0
;
i
<
myMessageClusters
.
size
();
i
++)
{
...
...
@@ -255,7 +269,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
}
});
if
(
my
InternalMod
e
)
{
if
(
my
AssigneeVisibl
e
)
{
myAssigneeCombo
=
new
ComboBox
<>();
myAssigneeCombo
.
setRenderer
(
new
ListCellRendererWrapper
<
Developer
>()
{
@Override
...
...
@@ -312,7 +326,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
attachmentsPanel
.
add
(
scrollPane
(
myAttachmentArea
,
500
,
350
),
BorderLayout
.
CENTER
);
JPanel
accountRow
=
new
JPanel
(
new
BorderLayout
());
if
(
my
InternalMod
e
)
accountRow
.
add
(
myAssigneePanel
,
BorderLayout
.
WEST
);
if
(
my
AssigneeVisibl
e
)
accountRow
.
add
(
myAssigneePanel
,
BorderLayout
.
WEST
);
accountRow
.
add
(
myCredentialsLabel
,
BorderLayout
.
EAST
);
myNoticePanel
=
new
JPanel
(
new
GridBagLayout
());
myNoticePanel
.
add
(
new
JBLabel
(
UIUtil
.
getBalloonWarningIcon
()),
new
GridBagConstraints
(
0
,
0
,
1
,
1
,
0
,
0
,
NORTH
,
NONE
,
JBUI
.
insets
(
7
,
0
,
0
,
5
),
0
,
0
));
...
...
@@ -341,7 +355,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
@Override
protected
Action
[]
createActions
()
{
List
<
Action
>
actions
=
new
ArrayList
<>();
if
(
my
InternalMod
e
&&
myProject
!=
null
&&
!
myProject
.
isDefault
())
{
if
(
my
AssigneeVisibl
e
&&
myProject
!=
null
&&
!
myProject
.
isDefault
())
{
AnAction
action
=
ActionManager
.
getInstance
().
getAction
(
"Unscramble"
);
if
(
action
!=
null
)
{
actions
.
add
(
new
AnalyzeAction
(
action
));
...
...
@@ -411,7 +425,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
updateLabels
(
cluster
);
updateDetails
(
cluster
);
if
(
my
InternalMod
e
)
{
if
(
my
AssigneeVisibl
e
)
{
updateAssigneePanel
(
cluster
);
}
updateCredentialsPanel
(
submitter
);
...
...
@@ -541,8 +555,13 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
myAssigneeCombo
.
setSelectedIndex
(-
1
);
}
else
{
Condition
<
Developer
>
lookup
=
d
->
Objects
.
equals
(
assignee
,
d
.
getId
());
myAssigneeCombo
.
setSelectedIndex
(
ContainerUtil
.
indexOf
(
ourDevelopersList
,
lookup
));
int
assigneeIndex
=
getAssigneeIndex
(
assignee
);
if
(
assigneeIndex
!=
-
1
)
{
myAssigneeCombo
.
setSelectedIndex
(
assigneeIndex
);
}
else
{
cluster
.
first
.
setAssigneeId
(
null
);
}
}
}
else
{
...
...
@@ -550,6 +569,16 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
}
}
private
int
getAssigneeIndex
(
Integer
assigneeId
)
{
for
(
int
index
=
0
;
index
<
myAssigneeCombo
.
getItemCount
();
index
++)
{
if
(
Objects
.
equals
(
assigneeId
,
myAssigneeCombo
.
getItemAt
(
index
).
getId
()))
{
return
index
;
}
}
return
-
1
;
}
private
void
updateCredentialsPanel
(
ErrorReportSubmitter
submitter
)
{
if
(
submitter
instanceof
ITNReporter
)
{
myCredentialsLabel
.
setVisible
(
true
);
...
...
@@ -571,6 +600,8 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
if
(
submitter
==
null
)
return
false
;
AbstractMessage
message
=
cluster
.
first
;
message
.
setAssigneeVisible
(
myAssigneeVisible
);
message
.
setDevelopersTimestamp
(
myDevelopersTimestamp
);
message
.
setSubmitting
(
true
);
String
notice
=
submitter
.
getPrivacyNoticeText
();
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help