Skip to content

Commit

Permalink
put key into errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dnfield committed Feb 22, 2021
1 parent d880def commit 813a769
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
16 changes: 13 additions & 3 deletions lib/src/svg/parser_state.dart
Expand Up @@ -106,6 +106,7 @@ class _Elements {
id,
<Drawable>[],
parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
viewBox!.viewBoxRect,
Expand All @@ -122,6 +123,7 @@ class _Elements {
<Drawable>[],
parserState._definitions,
parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
viewBox.viewBoxRect,
Expand All @@ -138,6 +140,7 @@ class _Elements {
parserState.attribute('id', def: ''),
<Drawable>[],
parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
parserState.rootBounds,
Expand All @@ -159,6 +162,7 @@ class _Elements {
parserState.attribute('id', def: ''),
<Drawable>[],
parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
null,
Expand All @@ -178,6 +182,7 @@ class _Elements {
}

final DrawableStyle style = parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
parserState.rootBounds,
Expand Down Expand Up @@ -240,7 +245,9 @@ class _Elements {
}

static Future<void>? radialGradient(
SvgParserState parserState, bool warningsAsErrors) {
SvgParserState parserState,
bool warningsAsErrors,
) {
final String? gradientUnits = getAttribute(
parserState.attributes,
'gradientUnits',
Expand All @@ -267,7 +274,7 @@ class _Elements {
final DrawableGradient? ref =
parserState._definitions.getGradient<DrawableGradient>('url($href)');
if (ref == null) {
reportMissingDef(href, 'radialGradient');
reportMissingDef(parserState._key, href, 'radialGradient');
} else {
if (gradientUnits == null) {
isObjectBoundingBox =
Expand Down Expand Up @@ -356,7 +363,7 @@ class _Elements {
final DrawableGradient? ref =
parserState._definitions.getGradient<DrawableGradient>('url($href)');
if (ref == null) {
reportMissingDef(href, 'linearGradient');
reportMissingDef(parserState._key, href, 'linearGradient');
} else {
if (gradientUnits == null) {
isObjectBoundingBox =
Expand Down Expand Up @@ -514,6 +521,7 @@ class _Elements {
image,
offset,
parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
parserState.rootBounds,
Expand Down Expand Up @@ -595,6 +603,7 @@ class _Elements {

textInfos.add(_TextInfo(
parseStyle(
parserState._key,
parserState.attributes,
parserState._definitions,
parserState.rootBounds,
Expand Down Expand Up @@ -867,6 +876,7 @@ class SvgParserState {
getAttribute(attributes, 'id', def: ''),
path,
parseStyle(
_key,
attributes,
_definitions,
path.getBounds(),
Expand Down
38 changes: 28 additions & 10 deletions lib/src/svg/xml_parsers.dart
Expand Up @@ -152,12 +152,17 @@ double? parseOpacity(List<XmlEventAttribute>? attributes) {
return null;
}

DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri,
DrawableDefinitionServer definitions, Rect bounds,
{double? opacity}) {
DrawablePaint _getDefinitionPaint(
String? key,
PaintingStyle paintingStyle,
String iri,
DrawableDefinitionServer definitions,
Rect bounds, {
double? opacity,
}) {
final Shader? shader = definitions.getShader(iri, bounds);
if (shader == null) {
reportMissingDef(iri, '_getDefinitionPaint');
reportMissingDef(key, iri, '_getDefinitionPaint');
}

return DrawablePaint(
Expand All @@ -169,6 +174,7 @@ DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri,

/// Parses a @stroke attribute into a [Paint].
DrawablePaint? parseStroke(
String? key,
List<XmlEventAttribute>? attributes,
Rect? bounds,
DrawableDefinitionServer definitions,
Expand All @@ -188,6 +194,7 @@ DrawablePaint? parseStroke(

if (rawStroke.startsWith('url')) {
return _getDefinitionPaint(
key,
PaintingStyle.stroke,
rawStroke,
definitions,
Expand Down Expand Up @@ -236,11 +243,13 @@ DrawablePaint? parseStroke(

/// Parses a `fill` attribute.
DrawablePaint? parseFill(
List<XmlEventAttribute>? el,
Rect? bounds,
DrawableDefinitionServer definitions,
DrawablePaint? parentFill,
Color? defaultFillColor) {
String? key,
List<XmlEventAttribute>? el,
Rect? bounds,
DrawableDefinitionServer definitions,
DrawablePaint? parentFill,
Color? defaultFillColor,
) {
final String rawFill = getAttribute(el, 'fill')!;
final String? rawFillOpacity = getAttribute(el, 'fill-opacity', def: '1.0');
final String? rawOpacity = getAttribute(el, 'opacity');
Expand All @@ -251,6 +260,7 @@ DrawablePaint? parseFill(

if (rawFill.startsWith('url')) {
return _getDefinitionPaint(
key,
PaintingStyle.fill,
rawFill,
definitions,
Expand Down Expand Up @@ -391,6 +401,7 @@ FontWeight? parseFontWeight(String? fontWeight) {
///
/// Remember that @style attribute takes precedence.
DrawableStyle parseStyle(
String? key,
List<XmlEventAttribute>? attributes,
DrawableDefinitionServer definitions,
Rect? bounds,
Expand All @@ -399,10 +410,17 @@ DrawableStyle parseStyle(
}) {
return DrawableStyle.mergeAndBlend(
parentStyle,
stroke: parseStroke(attributes, bounds, definitions, parentStyle?.stroke),
stroke: parseStroke(
key,
attributes,
bounds,
definitions,
parentStyle?.stroke,
),
dashArray: parseDashArray(attributes),
dashOffset: parseDashOffset(attributes),
fill: parseFill(
key,
attributes,
bounds,
definitions,
Expand Down
4 changes: 2 additions & 2 deletions lib/src/utilities/errors.dart
@@ -1,7 +1,7 @@
import 'package:flutter/foundation.dart';

/// Reports a missing or undefined `<defs>` element.
void reportMissingDef(String? href, String methodName) {
void reportMissingDef(String? key, String? href, String methodName) {
FlutterError.onError!(
FlutterErrorDetails(
exception: FlutterError.fromParts(<DiagnosticsNode>[
Expand All @@ -15,7 +15,7 @@ void reportMissingDef(String? href, String methodName) {
ErrorDescription(
'This error is treated as non-fatal, but your SVG file will likely not render as intended'),
]),
context: ErrorDescription('in $methodName'),
context: ErrorDescription('while parsing $key in $methodName'),
library: 'SVG',
),
);
Expand Down
31 changes: 31 additions & 0 deletions test/error_test.dart
@@ -0,0 +1,31 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:flutter_svg/parser.dart';

void main() {
testWidgets('Reports tag in out of order defs', (WidgetTester tester) async {
final FlutterExceptionHandler oldHandler = FlutterError.onError!;
late FlutterErrorDetails error;
FlutterError.onError = (FlutterErrorDetails details) {
error = details;
};
const String svgStr = '''
<svg id="svgRoot" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 166 202">
<path id="path4" d="M79.5 170.7 120.9 156.4 107.4 142.8" fill="url(#triangleGradient)" />
<defs>
<linearGradient id="triangleGradient">
<stop offset="20%" stop-color="#000000" stop-opacity=".55" />
<stop offset="85%" stop-color="#616161" stop-opacity=".01" />
</linearGradient>
</defs>
</svg>
''';

final SvgParser parser = SvgParser();
await parser.parse(svgStr, key: 'some_svg.svg');

expect(error.context.toString(), contains('while parsing some_svg.svg in _getDefinitionPaint'));
FlutterError.onError = oldHandler;
});
}

0 comments on commit 813a769

Please sign in to comment.