-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Uncaught TypeError: Failed to execute 'createRadialGradient' on … #898
Conversation
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
src/canvas/helper.ts
Outdated
@@ -4,30 +4,36 @@ import { GradientObject } from '../graphic/Gradient'; | |||
import { RectLike } from '../core/BoundingRect'; | |||
import Path from '../graphic/Path'; | |||
|
|||
export function safeNum(num: number, defalutNum: number = 0, negative = false) { | |||
// null NaN or empty string | |||
if (num === null || isNaN(num) || `${num}` === '') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems isNaN(num)
also includes null
and ''
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the last submit have removed
src/canvas/helper.ts
Outdated
@@ -4,30 +4,41 @@ import { GradientObject } from '../graphic/Gradient'; | |||
import { RectLike } from '../core/BoundingRect'; | |||
import Path from '../graphic/Path'; | |||
|
|||
export function safeNum(num: number, defalutNum: number = 0, negative = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use name nonNegative
will be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have changed
If we filter these illegal values in the underlying zrender without any warnings, will it hide potential errors of arguments passed from the upper application like ECharts? Most of the time, I think such an issue is caused by error arguments from the callers. |
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
I think we should check the parameters to make sure there are no errors. |
It may be more difficult for the developers to find out why they didn't get the expected result as no errors were thrown and no warnings were output. |
Usually we prefer warning logs over exceptions when having invalid values. |
How about giving warning as well as doing such safe guarding? |
ok! |
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
I add a warning in this pr . I'm not going to change the createLinearGradient method. |
src/canvas/helper.ts
Outdated
return false; | ||
} | ||
// NaN, Infinity, undefined, 'xx' | ||
if (!isFinite(num)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!isFinite
also includes num === null
check.
These three check can be merged to:
if (!isFinite(num) || (nonNegative && num < 0 {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry it's my mistake. null
can be convert to 0
here. I rechecked if null
can be used as argument of createLinearGradient
and seems it can. But undefined
will throw an non-finite
exception. So if we mainly wan using this check to avoid exceptions, we can still remove null
check.
src/canvas/helper.ts
Outdated
if (!obj.global) { | ||
x = x * width + rect.x; | ||
y = y * height + rect.y; | ||
r = r * min; | ||
} | ||
|
||
if (!isSafeNum(x) || !isSafeNum(y) || !isSafeNum(r, true)) { | ||
console.warn('The provided value is non-finite. You must provide x and y.'); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return nothing here is not safe. Because we expect this method to return a CanvasGradient and set it to CanvasRenderingContext. If we return null
, it will be an undefined behavior.
I think we can fallback to default value when the x
, y
, r
is invalid like createLinearGradient
did.
Also there are several concerns about this warn message being to frequently:
- It should be warn only once if the
CanvasGradientObject
is not changed. UseWeakMap
to mark thisCanvasGradientObject
has been warned may be a solution. - The
boundingRect
sometimes may be infinite or NaN(when we don't want to show the element) and leading thisx
,y
,r
to be invalid. In this case, the error message will not be helpful but confuse the
developers. So it's better to check theobj.x
,obj.y
,obj.r
earlier and give warning message. Then we do checkx
,y
,r
again and fallback to default value. - The check of
obj.x
,obj.y
,obj.r
and warning message can be done only whenprocess.env.NODE_ENV !== 'production'
so these can be ommitted in the production environment.
At last the createLinearGradient
should do the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…'CanvasRenderingContext2D': The provided double value is non-finite. at createRadialGradient. Excute npm run test error fix! (#16649)
src/canvas/helper.ts
Outdated
if (!obj.global) { | ||
x = x * width + rect.x; | ||
y = y * height + rect.y; | ||
r = r * min; | ||
} | ||
|
||
x = isSafeNum(x) ? x : 0.5; | ||
y = isSafeNum(y) ? y : 0.5; | ||
r = isSafeNum(r, true) ? r : 0.5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems only one number needs to be check positive. In this case I will prefer keeping the isSafeNum
simpler and more cohesion that only accept one parameter number
. Monomorphic function is always better than polymorphic function, on both code style and performance.
So the r
check can be
r = isSafeNum(r) && r >= 0 ? r : 0.5
@@ -12,7 +12,7 @@ describe('Path', function () { | |||
cy: 625.5, | |||
startAngle: -1.5707963267948966, | |||
endAngle: 4.71238898038469, | |||
innerCornerRadius: 5, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change seems to be unnecessary?
fix(gradient): #898 has bug about safe checkingand breaks all gradients
…'CanvasRenderingContext2D': The provided double value is non-finite.
The bug in Echarts apache/echarts#16649