rsocket / rsocket-js

JavaScript implementation of RSocket

Home Page:https://github.com/rsocket/rsocket-js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error type is missing the source property

AndyOGo opened this issue · comments

RSocket error frames are turning into standard Error() objects, and expanded by a source property.
The Error type does not reflect that fact.

Expected Behavior

All errors should be of a custom error type, if applicable.
And type guards could be useful too.

interface RSocketErrorSource {
  code: number;
  explanation: string;
  message: string;
}

interface RSocketError extends Error {
  source: RSocketErrorSource;
}
function isRSocketError(value: any): value is RSocketError {
  return Object.prototype.toString.call(value) === "[object Error]" && isRSocketErrorSource(value.source);
}

function isRSocketErrorSource(value: any): value is RSocketErrorSource {
  return source && source?.code && source?.explanation && source?.message;
}

Actual Behavior

Insufficient Error type is used, this prohibits auto-completion and discovery.

Affected code examples:

  • export function createErrorFromFrame(frame: ErrorFrame): Error {
    const {code, message} = frame;
    const explanation = getErrorCodeExplanation(code);
    const error = new Error(
    sprintf(
    'RSocket error %s (%s): %s. See error `source` property for details.',
    toHex(code),
    explanation,
    message,
    ),
    );
    (error: any).source = {
    code,
    explanation,
    message,
    };
    return error;
    }

Possible Solution

Please see expected above, it shows an interface.

Your Environment

  • RSocket version(s) used: 0.0.25

Hey, @AndyOGo! Could you elaborate on what the desired change is? While createErrorFromFrame creates an error that has a type that can be described as RSocketError, the other references types, e.g. Flowable.js can accept any error, not necessarily an error having the source property.

Hi @SerCeMan ! Thank you for your reply.

That is my point, createErrorFromFrame returns type Error.
This typing is wrong, what it really returns is an extended error object, therefore the type should be RSocketError

export function createErrorFromFrame(frame: ErrorFrame): Error {

It should change to:

export function createErrorFromFrame(frame: ErrorFrame): RSocketError { 

You are right, other refs can accept any error.

For these cases a type guard would be great, like:

function isRSocketError(value: any): value is RSocketError {
  return Object.prototype.toString.call(value) === "[object Error]" && isRSocketErrorSource(value.source);
}

function isRSocketErrorSource(value: any): value is RSocketErrorSource {
  return source && source?.code && source?.explanation && source?.message;
}

Hey @AndyOGo , @SerCeMan,

Is my understanding correct that this mostly causes issues with developer experience related to code completion and IDE functionality? If so, I would propose that this is like a "won't fix", since we are primarily focused on #158, which will aim to provide better TypeScript support. Please let me know if I am misunderstanding.

@viglucci
Our use case was mainly for error reporting and is production critical.

Anyway you are right too, it also enhances code completion.
#158 sounds great.