errors.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /**
  2. * Occurs when a read operation was cancelled
  3. */
  4. class ReadCancelledError extends Error {
  5. constructor() {
  6. super("You must run `python3 tl_generator.py` first. #ReadTheDocs!")
  7. }
  8. }
  9. /**
  10. * Occurs when you should've ran `tl_generator.py`, but you haven't
  11. */
  12. class TLGeneratorNotRan extends Error {
  13. constructor() {
  14. super("You must run `python3 tl_generator.py` first. #ReadTheDocs!")
  15. }
  16. }
  17. /**
  18. * Occurs when an invalid parameter is given, for example,
  19. * when either A or B are required but none is given
  20. */
  21. class InvalidParameterError extends Error {
  22. }
  23. /**
  24. * Occurs when a type is not found, for example,
  25. * when trying to read a TLObject with an invalid constructor code
  26. */
  27. class TypeNotFoundError extends Error {
  28. constructor(invalidConstructorId) {
  29. super('Could not find a matching Constructor ID for the TLObject ' +
  30. 'that was supposed to be read with ID {}. Most likely, a TLObject ' +
  31. 'was trying to be read when it should not be read.'.replace("{}",
  32. invalidConstructorId.toString("16")));
  33. this.invalidConstructorId = invalidConstructorId;
  34. }
  35. }
  36. /**
  37. * Occurs when a read operation was cancelled
  38. */
  39. class InvalidDCError extends Error {
  40. constructor(newDC) {
  41. super('Your phone number is registered to #{} DC. ' +
  42. 'This should have been handled automatically; ' +
  43. 'if it has not, please restart the app.'.replace("{}", newDC));
  44. this.newDC = newDC;
  45. }
  46. }
  47. /**
  48. * Occurs when an invalid checksum is passed
  49. */
  50. class InvalidChecksumError extends Error {
  51. constructor(checksum, validChecksum) {
  52. super('Invalid checksum ({0} when {1} was expected). This packet should be skipped.'
  53. .replace("{0}", checksum).replace("{1}", validChecksum));
  54. this.checksum = checksum;
  55. this.validChecksum = validChecksum;
  56. }
  57. }
  58. class RPCError extends Error {
  59. static CodeMessages = {
  60. 303: Array('ERROR_SEE_OTHER', 'The request must be repeated, but directed to a different data center.'),
  61. 400: Array('BAD_REQUEST', 'The query contains errors. In the event that a request was created using a ' +
  62. 'form and contains user generated data, the user should be notified that the ' +
  63. 'data must be corrected before the query is repeated.'),
  64. 401: Array('UNAUTHORIZED', 'There was an unauthorized attempt to use functionality available only to ' +
  65. 'authorized users.'),
  66. 403: Array('FORBIDDEN', 'Privacy violation. For example, an attempt to write a message to someone who ' +
  67. 'has blacklisted the current user.'),
  68. 404: Array('NOT_FOUND', 'An attempt to invoke a non-existent object, such as a method.'),
  69. 420: Array('FLOOD', 'The maximum allowed number of attempts to invoke the given method with ' +
  70. 'the given input parameters has been exceeded. For example, in an attempt ' +
  71. 'to request a large number of text messages (SMS) for the same phone number.'),
  72. 500: Array('INTERNAL', 'An internal server error occurred while a request was being processed; ' +
  73. 'for example, there was a disruption while accessing a database or file storage.')
  74. };
  75. static ErrorMessages = {
  76. // 303 ERROR_SEE_OTHER
  77. 'FILE_MIGRATE_(\\d+)': 'The file to be accessed is currently stored in a different data center (#{}).',
  78. 'PHONE_MIGRATE_(\\d+)': 'The phone number a user is trying to use for authorization is associated ' +
  79. 'with a different data center (#{}).',
  80. 'NETWORK_MIGRATE_(\\d+)': 'The source IP address is associated with a different data center (#{}, ' +
  81. 'for registration).',
  82. 'USER_MIGRATE_(\\d+)': 'The user whose identity is being used to execute queries is associated with ' +
  83. 'a different data center (#{} for registration).',
  84. // 400 BAD_REQUEST
  85. 'FIRSTNAME_INVALID': 'The first name is invalid.',
  86. 'LASTNAME_INVALID': 'The last name is invalid.',
  87. 'PHONE_NUMBER_INVALID': 'The phone number is invalid.',
  88. 'PHONE_CODE_HASH_EMPTY': 'phone_code_hash is missing.',
  89. 'PHONE_CODE_EMPTY': 'phone_code is missing.',
  90. 'PHONE_CODE_EXPIRED': 'The confirmation code has expired.',
  91. 'API_ID_INVALID': 'The api_id/api_hash combination is invalid.',
  92. 'PHONE_NUMBER_OCCUPIED': 'The phone number is already in use.',
  93. 'PHONE_NUMBER_UNOCCUPIED': 'The phone number is not yet being used.',
  94. 'USERS_TOO_FEW': 'Not enough users (to create a chat, for example).',
  95. 'USERS_TOO_MUCH': 'The maximum number of users has been exceeded (to create a chat, for example).',
  96. 'TYPE_CONSTRUCTOR_INVALID': 'The type constructor is invalid.',
  97. 'FILE_PART_INVALID': 'The file part number is invalid.',
  98. 'FILE_PARTS_INVALID': 'The number of file parts is invalid.',
  99. 'FILE_PART_(\\d+)_MISSING': 'Part {} of the file is missing from storage.',
  100. 'MD5_CHECKSUM_INVALID': 'The MD5 checksums do not match.',
  101. 'PHOTO_INVALID_DIMENSIONS': 'The photo dimensions are invalid.',
  102. 'FIELD_NAME_INVALID': 'The field with the name FIELD_NAME is invalid.',
  103. 'FIELD_NAME_EMPTY': 'The field with the name FIELD_NAME is missing.',
  104. 'MSG_WAIT_FAILED': 'A waiting call returned an error.',
  105. 'CHAT_ADMIN_REQUIRED': 'Chat admin privileges are required to do that in the specified chat ' +
  106. '(for example, to send a message in a channel which is not yours).',
  107. // 401 UNAUTHORIZED
  108. 'AUTH_KEY_UNREGISTERED': 'The key is not registered in the system.',
  109. 'AUTH_KEY_INVALID': 'The key is invalid.',
  110. 'USER_DEACTIVATED': 'The user has been deleted/deactivated.',
  111. 'SESSION_REVOKED': 'The authorization has been invalidated, because of the user terminating all sessions.',
  112. 'SESSION_EXPIRED': 'The authorization has expired.',
  113. 'ACTIVE_USER_REQUIRED': 'The method is only available to already activated users.',
  114. 'AUTH_KEY_PERM_EMPTY': 'The method is unavailable for temporary authorization key, not bound to permanent.',
  115. // 420 FLOOD
  116. 'FLOOD_WAIT_(\\d+)': 'A wait of {} seconds is required.'
  117. };
  118. constructor(code, message) {
  119. let codeMeaning = RPCError.CodeMessages[code];
  120. let mustResend = code === 303; // ERROR_SEE_OTHER, "The request must be repeated"
  121. let calledSuper = false;
  122. for (let item in RPCError.ErrorMessages) {
  123. let key = new RegExp(item);
  124. let errorMsg = RPCError.ErrorMessages[item];
  125. let match = message.match(key);
  126. if (match) {
  127. console.log(match[1]);
  128. // Get additionalData if any
  129. if (match.length === 2) {
  130. console.log(errorMsg);
  131. let additionalData = parseInt(match[1]);
  132. super(errorMsg.replace("{}", additionalData));
  133. this.additionalData = additionalData;
  134. } else {
  135. super(errorMsg);
  136. }
  137. calledSuper = true;
  138. break;
  139. }
  140. }
  141. if (!calledSuper) {
  142. super("Unknown error message with code {0}: {1}"
  143. .replace("{0}", code).replace("{1}", message))
  144. }
  145. this.code = code;
  146. this.errorMessage = message;
  147. this.codeMeaning = codeMeaning;
  148. this.mustResend = mustResend;
  149. }
  150. }
  151. /**
  152. * Occurs when handling a badMessageNotification
  153. */
  154. class BadMessageError extends Error {
  155. static ErrorMessages = {
  156. 16: 'msg_id too low (most likely, client time is wrong it would be worthwhile to ' +
  157. 'synchronize it using msg_id notifications and re-send the original message ' +
  158. 'with the “correct” msg_id or wrap it in a container with a new msg_id if the ' +
  159. 'original message had waited too long on the client to be transmitted).',
  160. 17: 'msg_id too high (similar to the previous case, the client time has to be ' +
  161. 'synchronized, and the message re-sent with the correct msg_id).',
  162. 18: 'Incorrect two lower order msg_id bits (the server expects client message msg_id ' +
  163. 'to be divisible by 4).',
  164. 19: 'Container msg_id is the same as msg_id of a previously received message ' +
  165. '(this must never happen).',
  166. 20: 'Message too old, and it cannot be verified whether the server has received a ' +
  167. 'message with this msg_id or not.',
  168. 32: 'msg_seqno too low (the server has already received a message with a lower ' +
  169. 'msg_id but with either a higher or an equal and odd seqno).',
  170. 33: 'msg_seqno too high (similarly, there is a message with a higher msg_id but with ' +
  171. 'either a lower or an equal and odd seqno).',
  172. 34: 'An even msg_seqno expected (irrelevant message), but odd received.',
  173. 35: 'Odd msg_seqno expected (relevant message), but even received.',
  174. 48: 'Incorrect server salt (in this case, the bad_server_salt response is received with ' +
  175. 'the correct salt, and the message is to be re-sent with it).',
  176. 64: 'Invalid container.'
  177. };
  178. constructor(code) {
  179. super(BadMessageError.ErrorMessages[code] || "Unknown error code (this should not happen): {}."
  180. .replace("{}", code));
  181. }
  182. }
  183. module.exports = {
  184. ReadCancelledError,
  185. TLGeneratorNotRan,
  186. InvalidParameterError,
  187. TypeNotFoundError,
  188. InvalidDCError,
  189. InvalidChecksumError,
  190. RPCError,
  191. BadMessageError
  192. };