Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
XWiki
xwiki-rendering
Commits
8a6e913d
Commit
8a6e913d
authored
Dec 06, 2021
by
Thomas Mortagne
Browse files
XRENDERING-621: Make rendering errors translatables and extendables
* simplify the API * make the code more reusable
parent
703f830b
Changes
4
Hide whitespace changes
Inline
Side-by-side
xwiki-rendering-api/src/main/java/org/xwiki/rendering/internal/util/DefaultErrorBlockGenerator.java
View file @
8a6e913d
...
...
@@ -28,9 +28,15 @@
import
javax.inject.Inject
;
import
javax.inject.Singleton
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.exception.ExceptionUtils
;
import
org.slf4j.Logger
;
import
org.xwiki.component.annotation.Component
;
import
org.xwiki.logging.LogLevel
;
import
org.xwiki.logging.LogUtils
;
import
org.xwiki.logging.event.LogEvent
;
import
org.xwiki.logging.marker.TranslationMarker
;
import
org.xwiki.rendering.block.Block
;
import
org.xwiki.rendering.block.FormatBlock
;
import
org.xwiki.rendering.block.GroupBlock
;
...
...
@@ -55,7 +61,21 @@ public class DefaultErrorBlockGenerator implements ErrorBlockGenerator
protected
Logger
logger
;
@Override
public
List
<
Block
>
generateErrorBlocks
(
String
message
,
String
description
,
boolean
isInline
)
public
List
<
Block
>
generateErrorBlocks
(
boolean
inline
,
String
messageId
,
String
defaultMessage
,
String
defaultDescription
,
Object
...
arguments
)
{
LogEvent
message
=
LogUtils
.
newLogEvent
(
messageId
!=
null
?
new
TranslationMarker
(
messageId
)
:
null
,
LogLevel
.
ERROR
,
defaultMessage
!=
null
&&
!
defaultMessage
.
endsWith
(
"."
)
?
defaultMessage
+
'.'
:
defaultMessage
,
arguments
);
LogEvent
description
=
defaultDescription
!=
null
?
LogUtils
.
newLogEvent
(
messageId
!=
null
?
new
TranslationMarker
(
messageId
+
".description"
)
:
null
,
LogLevel
.
ERROR
,
defaultDescription
,
arguments
)
:
null
;
return
generateErrorBlocks
(
inline
,
message
,
description
);
}
protected
List
<
Block
>
generateErrorBlocks
(
boolean
inline
,
LogEvent
message
,
LogEvent
description
)
{
List
<
Block
>
errorBlocks
=
new
ArrayList
<>();
...
...
@@ -64,39 +84,80 @@ public List<Block> generateErrorBlocks(String message, String description, boole
Map
<
String
,
String
>
errorDescriptionBlockParams
=
Collections
.
singletonMap
(
CLASS_ATTRIBUTE_NAME
,
CLASS_ATTRIBUTE_DESCRIPTION_VALUE
);
Block
descriptionBlock
=
new
VerbatimBlock
(
description
,
isInline
);
StringBuilder
messageBuilder
=
new
StringBuilder
();
if
(
StringUtils
.
isNotEmpty
(
message
.
getMessage
()))
{
messageBuilder
.
append
(
message
.
getFormattedMessage
());
}
List
<
Block
>
descriptionChildren
=
new
ArrayList
<>();
if
(
isInline
)
{
errorBlocks
.
add
(
new
FormatBlock
(
Arrays
.
asList
(
new
WordBlock
(
message
)),
Format
.
NONE
,
errorBlockParams
));
errorBlocks
.
add
(
new
FormatBlock
(
Arrays
.
asList
(
descriptionBlock
),
Format
.
NONE
,
errorDescriptionBlockParams
));
// Description
addDescriptionBlock
(
inline
,
description
,
descriptionChildren
);
// Stack trace
addStackTraceBlock
(
inline
,
message
,
messageBuilder
,
descriptionChildren
);
if
(!
descriptionChildren
.
isEmpty
())
{
messageBuilder
.
append
(
" Click on this message for details."
);
}
if
(
inline
)
{
errorBlocks
.
add
(
new
FormatBlock
(
Arrays
.
asList
(
new
WordBlock
(
messageBuilder
.
toString
())),
Format
.
NONE
,
errorBlockParams
));
if
(!
descriptionChildren
.
isEmpty
())
{
errorBlocks
.
add
(
new
FormatBlock
(
descriptionChildren
,
Format
.
NONE
,
errorDescriptionBlockParams
));
}
}
else
{
errorBlocks
.
add
(
new
GroupBlock
(
Arrays
.
asList
(
new
WordBlock
(
message
)),
errorBlockParams
));
errorBlocks
.
add
(
new
GroupBlock
(
Arrays
.
asList
(
descriptionBlock
),
errorDescriptionBlockParams
));
errorBlocks
.
add
(
new
GroupBlock
(
Arrays
.
asList
(
new
WordBlock
(
message
.
getFormattedMessage
())),
errorBlockParams
));
if
(!
descriptionChildren
.
isEmpty
())
{
errorBlocks
.
add
(
new
GroupBlock
(
descriptionChildren
,
errorDescriptionBlockParams
));
}
}
return
errorBlocks
;
}
@Override
public
List
<
Block
>
generateErrorBlocks
(
String
messagePrefix
,
Throwable
throwable
,
boolean
isInline
)
private
void
addDescriptionBlock
(
boolean
inline
,
LogEvent
description
,
List
<
Block
>
descriptionChildren
)
{
// Note: We're using ExceptionUtils.getRootCause(e).getMessage() instead of getRootCauseMessage()
// below because getRootCauseMessage() adds a technical prefix (the name of the exception), that
// we don't want to display to our users.
Throwable
rootCause
=
ExceptionUtils
.
getRootCause
(
throwable
);
if
(
rootCause
==
null
)
{
// If there's no nested exception, fall back to the throwable itself for getting the cause
rootCause
=
throwable
;
if
(
description
!=
null
)
{
descriptionChildren
.
add
(
new
VerbatimBlock
(
description
.
getFormattedMessage
(),
inline
));
}
}
private
void
addStackTraceBlock
(
boolean
inline
,
LogEvent
message
,
StringBuilder
messageBuilder
,
List
<
Block
>
descriptionChildren
)
{
if
(
message
.
getThrowable
()
!=
null
)
{
// Note: We're using ExceptionUtils.getRootCause(e).getMessage() instead of getRootCauseMessage()
// below because getRootCauseMessage() adds a technical prefix (the name of the exception), that
// we don't want to display to our users.
Throwable
rootCause
=
ExceptionUtils
.
getRootCause
(
message
.
getThrowable
());
if
(
rootCause
==
null
)
{
// If there's no nested exception, fall back to the throwable itself for getting the cause
rootCause
=
message
.
getThrowable
();
}
String
augmentedMessage
=
String
.
format
(
"%s%s"
,
messagePrefix
,
rootCause
==
null
?
""
:
String
.
format
(
". Cause: [%s]"
,
rootCause
.
getMessage
()));
augmentedMessage
=
String
.
format
(
"%s%sClick on this message for details."
,
augmentedMessage
,
augmentedMessage
.
trim
().
endsWith
(
"."
)
?
" "
:
". "
);
descriptionChildren
.
add
(
new
VerbatimBlock
(
ExceptionUtils
.
getStackTrace
(
message
.
getThrowable
()),
inline
));
this
.
logger
.
debug
(
augmentedMessage
);
// Also add more details to the message
messageBuilder
.
append
(
" Cause: ["
);
messageBuilder
.
append
(
rootCause
.
getMessage
());
messageBuilder
.
append
(
"]."
);
}
}
return
generateErrorBlocks
(
augmentedMessage
,
ExceptionUtils
.
getStackTrace
(
throwable
),
isInline
);
@Override
public
List
<
Block
>
generateErrorBlocks
(
String
message
,
String
description
,
boolean
isInline
)
{
return
generateErrorBlocks
(
isInline
,
null
,
message
,
description
,
ArrayUtils
.
EMPTY_OBJECT_ARRAY
);
}
@Override
public
List
<
Block
>
generateErrorBlocks
(
String
messagePrefix
,
Throwable
throwable
,
boolean
isInline
)
{
return
generateErrorBlocks
(
isInline
,
null
,
messagePrefix
,
null
,
throwable
);
}
@Override
...
...
xwiki-rendering-api/src/main/java/org/xwiki/rendering/util/ErrorBlockGenerator.java
View file @
8a6e913d
...
...
@@ -102,8 +102,8 @@
* context depending on the implementation of this component.
*
* @param inline whether the generated blocks should be inline or not
* @param m
arker a mark
er associated to the message. It's
recommended to at least pass a {@link TranslationMarker}
* t
o indicate how to translate the message
.
* @param m
essageId an identifi
er associated to the message. It's
generally used, among other things, to find a
* t
ranslation for the message and the description in implementation which supports it
.
* @param defaultMessage the default message following SLF4J's {@link Logger} syntax
* @param defaultDescription the default description following SLF4J's {@link Logger} syntax
* @param arguments a list arguments to insert in the message and the description and/or a {@link Throwable}
...
...
@@ -111,9 +111,10 @@
* @since 14.0RC1
*/
@Unstable
default
List
<
Block
>
generateErrorBlocks
(
boolean
inline
,
Marker
marker
,
String
defaultMessage
,
default
List
<
Block
>
generateErrorBlocks
(
boolean
inline
,
String
messageId
,
String
defaultMessage
,
String
defaultDescription
,
Object
...
arguments
)
{
Marker
marker
=
new
TranslationMarker
(
messageId
);
LogEvent
message
=
LogUtils
.
newLogEvent
(
marker
,
LogLevel
.
ERROR
,
defaultMessage
,
arguments
);
if
(
message
.
getThrowable
()
!=
null
)
{
...
...
xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/transformation/macro/MacroErrorManager.java
View file @
8a6e913d
...
...
@@ -22,8 +22,6 @@
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.Marker
;
import
org.xwiki.logging.marker.TranslationMarker
;
import
org.xwiki.rendering.block.Block
;
import
org.xwiki.rendering.block.MacroBlock
;
import
org.xwiki.rendering.block.MacroMarkerBlock
;
...
...
@@ -74,17 +72,17 @@ private Block wrapInMacroMarker(MacroBlock macroBlockToWrap, List<Block> newBloc
* Generates Blocks to signify that the passed Macro Block has failed to execute.
*
* @param macroToReplace
* @param m
arker a mark
er associated to the message. It's
recommended to at least pass a {@link TranslationMarker}
* t
o indicate how to translate the message
.
* @param m
essageId an identifi
er associated to the message. It's
generally used, among other things, to find a
* t
ranslation for the message and the description in implementation which supports it
.
* @param defaultMessage the default message following SLF4J's {@link Logger} syntax
* @param defaultDescription the default description following SLF4J's {@link Logger} syntax
* @param arguments a list arguments to insert in the message and the description and/or a {@link Throwable}
* @since 14.0RC1
*/
public
void
generateError
(
MacroBlock
macroToReplace
,
Marker
marker
,
String
defaultMessage
,
public
void
generateError
(
MacroBlock
macroToReplace
,
String
messageId
,
String
defaultMessage
,
String
defaultDescription
,
Object
...
arguments
)
{
List
<
Block
>
errorBlocks
=
this
.
errorBlockGenerator
.
generateErrorBlocks
(
macroToReplace
.
isInline
(),
m
arker
,
List
<
Block
>
errorBlocks
=
this
.
errorBlockGenerator
.
generateErrorBlocks
(
macroToReplace
.
isInline
(),
m
essageId
,
defaultMessage
,
defaultDescription
,
arguments
);
macroToReplace
.
getParent
().
replaceChild
(
wrapInMacroMarker
(
macroToReplace
,
errorBlocks
),
macroToReplace
);
}
...
...
xwiki-rendering-transformations/xwiki-rendering-transformation-macro/src/main/java/org/xwiki/rendering/internal/transformation/macro/MacroTransformation.java
View file @
8a6e913d
...
...
@@ -32,7 +32,6 @@
import
org.xwiki.component.annotation.Component
;
import
org.xwiki.component.phase.Initializable
;
import
org.xwiki.component.phase.InitializationException
;
import
org.xwiki.logging.marker.TranslationMarker
;
import
org.xwiki.properties.BeanManager
;
import
org.xwiki.rendering.block.Block
;
import
org.xwiki.rendering.block.MacroBlock
;
...
...
@@ -68,15 +67,15 @@
@Singleton
public
class
MacroTransformation
extends
AbstractTransformation
implements
Initializable
{
private
static
final
TranslationMarker
TM_UNKNOWNMACRO
=
new
TranslationMarker
(
"rendering.macro.error.unknown"
)
;
private
static
final
String
TM_UNKNOWNMACRO
=
"rendering.macro.error.unknown"
;
private
static
final
TranslationMarker
TM_FAILEDMACRO
=
new
TranslationMarker
(
"rendering.macro.error.failed"
)
;
private
static
final
String
TM_FAILEDMACRO
=
"rendering.macro.error.failed"
;
private
static
final
TranslationMarker
TM_INVALIDMACRO
=
new
TranslationMarker
(
"rendering.macro.error.invalid"
)
;
private
static
final
String
TM_INVALIDMACRO
=
"rendering.macro.error.invalid"
;
private
static
final
TranslationMarker
TM_STANDALONEMACRO
=
new
TranslationMarker
(
"rendering.macro.error.standalone"
)
;
private
static
final
String
TM_STANDALONEMACRO
=
"rendering.macro.error.standalone"
;
private
static
final
TranslationMarker
TM_INVALIDMACROPARAMETER
=
new
TranslationMarker
(
"rendering.macro.error.invalidParameter"
)
;
private
static
final
String
TM_INVALIDMACROPARAMETER
=
"rendering.macro.error.invalidParameter"
;
private
static
class
MacroLookupExceptionElement
{
...
...
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