{"record":{"id":"49ec11c6d2f70221","repo":"algorithm-visualizer/algorithm-visualizer","slug":"data-typeof-data-string-data-json-stri","errorCode":null,"errorMessage":"data ? typeof data === 'string' ? data : JSON.stringify(data) : statusText","messagePattern":"data \\? typeof data === 'string' \\? data : JSON\\.stringify\\(data\\) : statusText","errorType":"http","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/components/BaseComponent/index.js","lineNumber":13,"sourceCode":"import React from 'react';\n\nclass BaseComponent extends React.Component {\n  constructor(props) {\n    super(props);\n\n    this.handleError = this.handleError.bind(this);\n  }\n\n  handleError(error) {\n    if (error.response) {\n      const { data, statusText } = error.response;\n      const message = data ? typeof data === 'string' ? data : JSON.stringify(data) : statusText;\n      console.error(message);\n      this.props.showErrorToast(message);\n    } else {\n      console.error(error.message);\n      this.props.showErrorToast(error.message);\n    }\n  }\n}\n\nexport default BaseComponent;\n","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/algorithm-visualizer/algorithm-visualizer/blob/18de2edf6b629e843ee4bcedfa2208d22b253f0f/src/components/BaseComponent/index.js#L1-L24","documentation":"This is not a thrown error but a fragile expression in BaseComponent.handleError that extracts a message string from an axios error.response. The nested ternary `data ? typeof data === 'string' ? data : JSON.stringify(data) : statusText` has two failure modes: (1) JSON.stringify(data) throws a TypeError if data is an object with circular references, and (2) if data is falsy and statusText is empty/undefined, the resulting `message` is undefined — which then propagates to console.error and showErrorToast.","triggerScenarios":"An API returns an error response where response.data is a non-serializable object (circular structure from a framework error envelope), or a response with an empty body and no statusText (e.g. a 502 from a proxy that strips headers). JSON.stringify throws and crashes handleError itself.","commonSituations":"Backend framework error serializers that include circular request/response objects, misconfigured reverse proxies returning bare status codes with no body, or axios interceptor (line 4 of apis/index.js) returning response.data as a complex object.","solutions":["Wrap JSON.stringify(data) in a try-catch with a fallback to statusText.","Provide a terminal fallback so message is never undefined: `... : statusText || 'Unknown error'`.","Use a safe-stringify utility (e.g. flatted or a custom replacer) if circular responses are expected from the backend."],"exampleFix":"// before\nconst message = data ? typeof data === 'string' ? data : JSON.stringify(data) : statusText;\n\n// after\nlet message;\ntry {\n  message = data ? (typeof data === 'string' ? data : JSON.stringify(data)) : statusText;\n} catch (e) {\n  message = statusText;\n}\nmessage = message || 'Unknown error';","handlingStrategy":"try-catch","validationCode":"// Pre-validate that data is safely serializable before calling JSON.stringify\nconst isSafeToSerialize = (data) => {\n  if (data == null || typeof data === 'string') return true;\n  if (typeof data !== 'object') return true;\n  try { JSON.stringify(data); return true; } catch { return false; }\n};","typeGuard":"const extractErrorMessage = (response) => {\n  if (!response) return null;\n  const { data, statusText } = response;\n  if (typeof data === 'string' && data.length > 0) return data;\n  if (data != null && typeof data === 'object') {\n    try { return JSON.stringify(data); } catch { return statusText || null; }\n  }\n  return statusText || null;\n};","tryCatchPattern":"// Wrap the entire message extraction defensively\nhandleError(error) {\n  let message;\n  if (error.response) {\n    const { data, statusText } = error.response;\n    try {\n      message = typeof data === 'string' ? data\n        : (data != null ? JSON.stringify(data) : null);\n    } catch (e) {\n      message = null;\n    }\n    message = message || statusText || `Request failed (${error.response.status})`;\n  } else {\n    message = (error instanceof Error ? error.message : String(error)) || 'Unknown error';\n  }\n  console.error(message, error);\n  this.props.showErrorToast(message);\n}","preventionTips":["Never call JSON.stringify on untrusted response data without a try-catch.","Always provide a terminal fallback string so message is never undefined.","Consider using a safe stringify library (flatted, safe-stable-stringify) for API error envelopes."],"tags":["error-handling","axios","json-stringify","base-component","type-safety"],"backgroundTag":null,"analyzedSha":"18de2edf6b629e843ee4bcedfa2208d22b253f0f","analyzedAt":"2026-08-13T02:05:39.355Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}