error.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. function getErrorStackTrace(e) {
  2. if (typeof e !== "object" || e == null)
  3. return undefined;
  4. if (!("stack" in e) || typeof e.stack !== "string")
  5. return undefined;
  6. let stack = e.stack;
  7. const prevLine = `${e}`;
  8. if (stack.startsWith(prevLine)) {
  9. stack = stack.slice(prevLine.length);
  10. }
  11. if (stack.startsWith("\n")) {
  12. stack = stack.slice(1);
  13. }
  14. return stack;
  15. }
  16. export function printErrorStackTrace(e) {
  17. const stack = getErrorStackTrace(e);
  18. if (stack == null)
  19. return;
  20. console.error(stack);
  21. }
  22. /**
  23. * LangSmithConflictError
  24. *
  25. * Represents an error that occurs when there's a conflict during an operation,
  26. * typically corresponding to HTTP 409 status code responses.
  27. *
  28. * This error is thrown when an attempt to create or modify a resource conflicts
  29. * with the current state of the resource on the server. Common scenarios include:
  30. * - Attempting to create a resource that already exists
  31. * - Trying to update a resource that has been modified by another process
  32. * - Violating a uniqueness constraint in the data
  33. *
  34. * @extends Error
  35. *
  36. * @example
  37. * try {
  38. * await createProject("existingProject");
  39. * } catch (error) {
  40. * if (error instanceof ConflictError) {
  41. * console.log("A conflict occurred:", error.message);
  42. * // Handle the conflict, e.g., by suggesting a different project name
  43. * } else {
  44. * // Handle other types of errors
  45. * }
  46. * }
  47. *
  48. * @property {string} name - Always set to 'ConflictError' for easy identification
  49. * @property {string} message - Detailed error message including server response
  50. *
  51. * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409
  52. */
  53. export class LangSmithConflictError extends Error {
  54. constructor(message) {
  55. super(message);
  56. Object.defineProperty(this, "status", {
  57. enumerable: true,
  58. configurable: true,
  59. writable: true,
  60. value: void 0
  61. });
  62. this.name = "LangSmithConflictError";
  63. this.status = 409;
  64. }
  65. }
  66. /**
  67. * Throws an appropriate error based on the response status and body.
  68. *
  69. * @param response - The fetch Response object
  70. * @param context - Additional context to include in the error message (e.g., operation being performed)
  71. * @throws {LangSmithConflictError} When the response status is 409
  72. * @throws {Error} For all other non-ok responses
  73. */
  74. export async function raiseForStatus(response, context, consume) {
  75. // consume the response body to release the connection
  76. // https://undici.nodejs.org/#/?id=garbage-collection
  77. let errorBody;
  78. if (response.ok) {
  79. if (consume) {
  80. errorBody = await response.text();
  81. }
  82. return;
  83. }
  84. errorBody = await response.text();
  85. const fullMessage = `Failed to ${context}. Received status [${response.status}]: ${response.statusText}. Server response: ${errorBody}`;
  86. if (response.status === 409) {
  87. throw new LangSmithConflictError(fullMessage);
  88. }
  89. const err = new Error(fullMessage);
  90. err.status = response.status;
  91. throw err;
  92. }