-
Notifications
You must be signed in to change notification settings - Fork 702
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
Error alert component #4084
Error alert component #4084
Conversation
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
dispatch( | ||
errorApp( | ||
e instanceof Error | ||
? new FetchError("Unable to list apps", [e]) |
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.
Only place where the new constructor for errors is used by now.
@@ -131,7 +131,7 @@ function AppList() { | |||
className="margin-t-xl" | |||
> | |||
{error ? ( | |||
<Alert theme="danger">Unable to list apps: {error.message}</Alert> | |||
<ErrorAlert>{error}</ErrorAlert> |
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.
Only usage of the new ErrorAlert
component by now.
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.
Great, just to confirm: you mean there are other errors out there (like there is a problem with this package...
) which are not being handled by this novel ErrorAlert
, don't you?
So this is just a kind of proof of concept, no?
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.
Exactly, I first wanted the community to review it. If accepted, we can start using it from now on and eventually replace existing <Alert>
with it.
@@ -0,0 +1,24 @@ | |||
export class RpcError extends Error { | |||
// Following https://github.com/grpc/grpc-go/blob/master/internal/status/status.go#L140 | |||
static RPC_ERROR_REGEX = /rpc error: code = (\w+) desc = (.*)/; |
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.
Until we can have GRPC code to properly throw a dedicated error object, we can only guess if it is an rpc error by checking the error message string.
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.
You should be able to check the grpc error code? At least, the gRPC dashboard code should be throwing an error object with a .code
property. That's what we're using here already: https://github.com/kubeapps/kubeapps/blob/master/dashboard/src/shared/Auth.ts#L71-L88
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.
Thanks, will definitely take a look. It would be simpler.
// via err.contructor == FOO | ||
constructor(message?: string) { | ||
// via err.constructor == FOO | ||
constructor(message?: string, causes?: Error[]) { |
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.
Allows to optionally specify a stack of causing errors.
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
import "./ErrorAlert.css"; | ||
|
||
export interface IErrorAlert { | ||
children: CustomError | Error | string; |
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.
Component supports rendering this three types.
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.
What if there are no children?
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.
Children is a mandatory item it seems. In this case doesn't make sense to show the error block without any content, does it?
This can be a complimentary work to #3723 |
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.
Great. It seems a great UI improvement; I only have some minor comments and questions but in general LGTM!
Thank you!
@@ -131,7 +131,7 @@ function AppList() { | |||
className="margin-t-xl" | |||
> | |||
{error ? ( | |||
<Alert theme="danger">Unable to list apps: {error.message}</Alert> | |||
<ErrorAlert>{error}</ErrorAlert> |
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.
Great, just to confirm: you mean there are other errors out there (like there is a problem with this package...
) which are not being handled by this novel ErrorAlert
, don't you?
So this is just a kind of proof of concept, no?
import "./ErrorAlert.css"; | ||
|
||
export interface IErrorAlert { | ||
children: CustomError | Error | string; |
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.
What if there are no children?
} else if (children instanceof Error) { | ||
messages = [createWrap(children.message, 0, false)]; | ||
} else { | ||
messages = [children]; |
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.
As above, what if we have no response from the other side of the wire. For example, the API server being OOMkilled by k8s and the gRPC call just returns the nginx error 502 page ? - meaning no explicit error message being sent.
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.
Same as commented above, it does not make sense to have the error block with empty data. For the error codes, it will show exactly the same as current <Alert>
component, just the passed children.
@@ -0,0 +1,9 @@ | |||
.error-alert-rpc { | |||
ul > li { | |||
font-weight: bolder; |
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.
We are using explicit numbers in the rest of the CSS files, usually 400, 500 or 600. See what you think
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.
Sure, will change it to be aligned 😃
font-weight: bolder; | ||
|
||
span.rpc-value { | ||
font-weight: normal; |
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.
Idem here
@@ -0,0 +1,24 @@ | |||
export class RpcError extends Error { |
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.
I wonder if we should rename Rpc
to GRpc
instead
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.
Yeah, I thought about it, but error message states rpc error:
so I went ahead with a generic rpc
naming for everything.
private extractData(message: string): [string, string, string] { | ||
const found = message.trim().match(RpcError.RPC_ERROR_REGEX); | ||
return found | ||
? [found[1], found[2], message.substring(0, message.indexOf(found[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.
I'd rather check found.length to avoid undesired undefined
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.
Added tests for empty strings and undefined and it seems ok.
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.
I was curious, so checked the match
return for empty strings. It is undefined, for a positive case, the data is in the array. So we are good.
Signed-off-by: Rafa Castelblanque <rcastelblanq@vmware.com>
Signed-off-by: Rafa Castelblanque rcastelblanq@vmware.com
Description of the change
Introduces a React
ErrorAlert
component aimed at improving readability of UI errors and that could replace existing<Alert>
usages.It is able to turn this kind of UI error:
into this:
It can detect RPC errors and show them indented while not affecting existing plain text errors.
The change also allows to specify a stack of errors when creating a custom error (or an extension of it).
Benefits
Better error readability on UI
Possible drawbacks
None that I can think of.