Skip to content

Commit

Permalink
feat: update Error messages
Browse files Browse the repository at this point in the history
Error messages are for humans.
Previously we use error name as the message.
This commit  replaces some confusing error messages
with more detailed explanations.

BREAKING CHANGE:
Some error messages is changed.
This is breaking if string comparison are used against error.message.
We suggest to use error.code or error.name for error handling.
PLEASE NOTE: In future, changes to error.message will not be considered breaking.
  • Loading branch information
leeyeh committed May 11, 2018
1 parent 3e108d0 commit e679437
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 11 deletions.
22 changes: 20 additions & 2 deletions realtime.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ declare namespace LeanCloudRealtime {
CLOSE_NORMAL,
CLOSE_ABNORMAL,
APP_NOT_AVAILABLE,
SIGNATURE_FAILED,
INVALID_LOGIN,
SESSION_REQUIRED,
READ_TIMEOUT,
Expand All @@ -361,18 +362,35 @@ declare namespace LeanCloudRealtime {
INVALID_ORIGIN,
SESSION_CONFLICT,
SESSION_TOKEN_EXPIRED,
APP_QUOTA_EXCEEDED,
MESSAGE_SENT_QUOTA_EXCEEDED,
INTERNAL_ERROR,
SEND_MESSAGE_TIMEOUT,
CONVERSATION_API_FAILED,
CONVERSATION_SIGNATURE_FAILED,
CONVERSATION_NOT_FOUND,
CONVERSATION_FULL,
CONVERSATION_REJECTED_BY_APP,
CONVERSATION_UPDATE_FAILED,
CONVERSATION_READ_ONLY,
CONVERSATION_NOT_ALLOWED,
CONVERSATION_EXPIRED,
CONVERSATION_UPDATE_REJECTED,
CONVERSATION_QUERY_FAILED,
CONVERSATION_LOG_FAILED,
CONVERSATION_LOG_REJECTED,
SYSTEM_CONVERSATION_REQUIRED,
NORMAL_CONVERSATION_REQUIRED,
CONVERSATION_BLACKLISTED,
TRANSIENT_CONVERSATION_REQUIRED,
CONVERSATION_MEMBERSHIP_REQUIRED,
CONVERSATION_API_QUOTA_EXCEEDED,
TEMPORARY_CONVERSATION_EXPIRED,
INVALID_MESSAGING_TARGET,
MESSAGE_REJECTED_BY_APP,
MESSAGE_OWNERSHIP_REQUIRED,
MESSAGE_NOT_FOUND,
MESSAGE_UPDATE_REJECTED_BY_APP,
MESSAGE_EDIT_DISABLED,
MESSAGE_RECALL_DISABLED,
}

export enum Event {
Expand Down
7 changes: 6 additions & 1 deletion src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ export default class Connection extends WebSocketPlus {
timeout: setTimeout(() => {
if (this._commands[serialId]) {
if (debug.enabled) debug('✗ %O timeout', trim(command));
reject(new Error('Command Timeout.'));
reject(
createError({
error: `Command Timeout [cmd:${command.cmd} op:${command.op}]`,
name: 'COMMAND_TIMEOUT',
})
);
delete this._commands[serialId];
}
}, COMMAND_TIMEOUT),
Expand Down
4 changes: 2 additions & 2 deletions src/conversations/temporary-conversation.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { decodeDate, getTime } from '../utils';

const transformNotFoundError = error =>
error.code === ErrorCode.CONVERSATION_NOT_FOUND
? createError({ code: ErrorCode.CONVERSATION_EXPIRED })
? createError({ code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED })
: error;

/**
Expand Down Expand Up @@ -48,7 +48,7 @@ class TemporaryConversation extends ConversationBase {

async _send(...args) {
if (this.expired)
throw createError({ code: ErrorCode.CONVERSATION_EXPIRED });
throw createError({ code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED });
try {
return await super._send(...args);
} catch (error) {
Expand Down
80 changes: 76 additions & 4 deletions src/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export const error = Object.freeze({
name: 'APP_NOT_AVAILABLE',
message: 'App not exists or realtime message service is disabled.',
},
4102: {
name: 'SIGNATURE_FAILED',
message: 'Login signature mismatch.',
},
4103: {
name: 'INVALID_LOGIN',
message: 'Malformed clientId.',
Expand Down Expand Up @@ -36,15 +40,25 @@ export const error = Object.freeze({
4112: {
name: 'SESSION_TOKEN_EXPIRED',
},
4113: {
name: 'APP_QUOTA_EXCEEDED',
message: 'The daily active users limit exceeded.',
},
4116: {
name: 'MESSAGE_SENT_QUOTA_EXCEEDED',
message: 'Command sent too fast.',
},
4200: {
name: 'INTERNAL_ERROR',
message: 'Internal error, please contact LeanCloud for support.',
},
4201: {
name: 'SEND_MESSAGE_TIMEOUT',
4301: {
name: 'CONVERSATION_API_FAILED',
message: 'Upstream Conversatoin API failed, see error.detail for details.',
},
4302: {
name: 'CONVERSATION_SIGNATURE_FAILED',
message: 'Conversation action signature mismatch.',
},
4303: {
name: 'CONVERSATION_NOT_FOUND',
Expand All @@ -54,6 +68,7 @@ export const error = Object.freeze({
},
4305: {
name: 'CONVERSATION_REJECTED_BY_APP',
message: 'Conversation action rejected by hook.',
},
4306: {
name: 'CONVERSATION_UPDATE_FAILED',
Expand All @@ -64,15 +79,69 @@ export const error = Object.freeze({
4308: {
name: 'CONVERSATION_NOT_ALLOWED',
},
4309: {
name: 'CONVERSATION_UPDATE_REJECTED',
message: 'Conversation update rejected because the client is not a member.',
},
4310: {
name: 'CONVERSATION_QUERY_FAILED',
message: 'Conversation query failed because it is too expansive.',
},
4311: {
name: 'CONVERSATION_LOG_FAILED',
},
4312: {
name: 'CONVERSATION_LOG_REJECTED',
message:
'Message query rejected because the client is not a member of the conversation.',
},
4313: {
name: 'SYSTEM_CONVERSATION_REQUIRED',
},
4314: {
name: 'NORMAL_CONVERSATION_REQUIRED',
},
4315: {
name: 'CONVERSATION_BLACKLISTED',
message: 'Blacklisted in the conversation.',
},
4316: {
name: 'TRANSIENT_CONVERSATION_REQUIRED',
},
4317: {
name: 'CONVERSATION_EXPIRED',
name: 'CONVERSATION_MEMBERSHIP_REQUIRED',
},
4318: {
name: 'CONVERSATION_API_QUOTA_EXCEEDED',
message: 'LeanCloud API quota exceeded. You may upgrade your plan.',
},
4323: {
name: 'TEMPORARY_CONVERSATION_EXPIRED',
message: 'Temporary conversation expired or does not exist.',
},
4401: {
name: 'INVALID_MESSAGING_TARGET',
message: 'Conversation does not exist or client is not a member.',
},
4402: {
name: 'MESSAGE_REJECTED_BY_APP',
message: 'Message rejected by hook.',
},
4403: {
name: 'MESSAGE_OWNERSHIP_REQUIRED',
},
4404: {
name: 'MESSAGE_NOT_FOUND',
},
4405: {
name: 'MESSAGE_UPDATE_REJECTED_BY_APP',
message: 'Message update rejected by hook.',
},
4406: {
name: 'MESSAGE_EDIT_DISABLED',
},
4407: {
name: 'MESSAGE_RECALL_DISABLED',
},
});

Expand All @@ -94,8 +163,10 @@ export const createError = ({
error: errorMessage,
}) => {
let message = reason || detail || errorMessage;
let name = reason;
if (!message && error[code]) {
message = error[code].message || error[code].name;
({ name } = error[code]);
message = error[code].message || name;
}
if (!message) {
message = `Unknow Error: ${code}`;
Expand All @@ -105,5 +176,6 @@ export const createError = ({
code,
appCode,
detail,
name,
});
};
6 changes: 4 additions & 2 deletions test/conversation.js
Original file line number Diff line number Diff line change
Expand Up @@ -754,14 +754,16 @@ describe('Conversation', () => {
conv.expired.should.eql(true);
await conv.send(new TextMessage('')).should.be.rejectedWith(Error, {
message: 'Temporary conversation expired or does not exist.',
code: ErrorCode.CONVERSATION_EXPIRED,
code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED,
name: 'TEMPORARY_CONVERSATION_EXPIRED',
});
// server expiration check
conv.expiredAt = Date.now() + 1000000;
conv.expired.should.eql(false);
return conv.send(new TextMessage('')).should.be.rejectedWith(Error, {
message: 'Temporary conversation expired or does not exist.',
code: ErrorCode.CONVERSATION_EXPIRED,
code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED,
name: 'TEMPORARY_CONVERSATION_EXPIRED',
});
});
it('serialize and parse', async () => {
Expand Down
1 change: 1 addition & 0 deletions test/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ describe('Messages', () => {
.then(conversation => conversation.send(message))
.should.be.rejectedWith(Error, {
message: 'INVALID_MESSAGING_TARGET',
name: 'INVALID_MESSAGING_TARGET',
code: ErrorCode.INVALID_MESSAGING_TARGET,
})
.then(() => {
Expand Down

0 comments on commit e679437

Please sign in to comment.