错误处理 #
常见错误类型 #
HTTP状态码 #
| 状态码 | 说明 | 处理方式 |
|---|---|---|
| 400 | 请求参数错误 | 检查参数格式 |
| 401 | 认证失败 | 检查API密钥 |
| 403 | 权限不足 | 检查密钥权限 |
| 404 | 资源不存在 | 检查索引名称 |
| 429 | 请求过多 | 实现限流 |
| 500 | 服务器错误 | 重试请求 |
错误响应结构 #
javascript
{
"message": "Index not found",
"status": 404,
"name": "ApiError"
}
错误处理策略 #
基本错误处理 #
javascript
try {
const results = await index.search('iphone');
} catch (error) {
console.error('Search failed:', error.message);
console.error('Status:', error.status);
}
按状态码处理 #
javascript
async function safeSearch(query) {
try {
return await index.search(query);
} catch (error) {
switch (error.status) {
case 400:
console.error('请求参数错误:', error.message);
return { hits: [], nbHits: 0 };
case 401:
console.error('API密钥无效');
throw new Error('认证失败');
case 403:
console.error('权限不足');
throw new Error('无访问权限');
case 404:
console.error('索引不存在');
return { hits: [], nbHits: 0 };
case 429:
console.error('请求过多,稍后重试');
await sleep(1000);
return safeSearch(query);
default:
console.error('未知错误:', error);
throw error;
}
}
}
重试机制 #
简单重试 #
javascript
async function retrySearch(query, maxRetries = 3) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await index.search(query);
} catch (error) {
lastError = error;
// 客户端错误不重试
if (error.status >= 400 && error.status < 500) {
throw error;
}
// 指数退避
await sleep(1000 * Math.pow(2, i));
}
}
throw lastError;
}
带退避的重试 #
javascript
async function searchWithBackoff(query, options = {}) {
const {
maxRetries = 3,
initialDelay = 1000,
maxDelay = 30000
} = options;
let delay = initialDelay;
for (let i = 0; i < maxRetries; i++) {
try {
return await index.search(query);
} catch (error) {
if (i === maxRetries - 1) throw error;
// 只重试服务端错误
if (error.status >= 500 || error.status === 429) {
await sleep(delay);
delay = Math.min(delay * 2, maxDelay);
} else {
throw error;
}
}
}
}
降级策略 #
返回缓存数据 #
javascript
async function searchWithFallback(query) {
try {
const results = await index.search(query);
cacheResults(query, results);
return results;
} catch (error) {
console.error('Search failed, using cache:', error.message);
const cached = getCachedResults(query);
if (cached) {
return cached;
}
return { hits: [], nbHits: 0 };
}
}
返回默认数据 #
javascript
async function searchWithDefault(query) {
try {
return await index.search(query);
} catch (error) {
console.error('Search failed:', error.message);
return {
hits: [],
nbHits: 0,
page: 0,
nbPages: 0,
error: true
};
}
}
前端错误处理 #
React错误边界 #
jsx
class SearchErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, info) {
console.error('Search error:', error, info);
}
render() {
if (this.state.hasError) {
return (
<div className="error-fallback">
<p>搜索出现错误,请稍后重试</p>
<button onClick={() => this.setState({ hasError: false })}>
重试
</button>
</div>
);
}
return this.props.children;
}
}
// 使用
<SearchErrorBoundary>
<SearchComponent />
</SearchErrorBoundary>
用户友好提示 #
javascript
function getErrorMessage(error) {
const messages = {
400: '搜索参数有误,请检查输入',
401: '请重新登录后再试',
403: '您没有权限执行此操作',
404: '未找到相关内容',
429: '请求过于频繁,请稍后再试',
500: '服务器繁忙,请稍后再试'
};
return messages[error.status] || '搜索失败,请稍后重试';
}
调试技巧 #
启用调试日志 #
javascript
const client = algoliasearch('APP_ID', 'API_KEY', {
logger: {
debug: console.log,
info: console.log,
error: console.error
}
});
记录请求详情 #
javascript
async function debugSearch(query, params) {
console.log('Search request:', {
query,
params,
timestamp: new Date().toISOString()
});
const start = Date.now();
try {
const results = await index.search(query, params);
console.log('Search response:', {
nbHits: results.nbHits,
processingTimeMS: results.processingTimeMS,
duration: Date.now() - start
});
return results;
} catch (error) {
console.error('Search error:', {
status: error.status,
message: error.message,
duration: Date.now() - start
});
throw error;
}
}
使用getRankingInfo #
javascript
const results = await index.search('iphone', {
getRankingInfo: true
});
results.hits.forEach(hit => {
console.log(hit.name, hit._rankingInfo);
});
错误监控 #
集成错误追踪 #
javascript
async function monitoredSearch(query) {
try {
return await index.search(query);
} catch (error) {
// 发送到错误追踪服务
trackError({
type: 'algolia_search_error',
query,
status: error.status,
message: error.message
});
throw error;
}
}
错误统计 #
javascript
const errorStats = {
total: 0,
byStatus: {}
};
function recordError(error) {
errorStats.total++;
errorStats.byStatus[error.status] =
(errorStats.byStatus[error.status] || 0) + 1;
}
function getErrorStats() {
return errorStats;
}
常见问题解决 #
索引不存在 #
javascript
// 检查索引是否存在
async function ensureIndex(indexName) {
try {
await client.initIndex(indexName).getSettings();
} catch (error) {
if (error.status === 404) {
// 创建索引
await client.initIndex(indexName).setSettings({});
}
}
}
API密钥无效 #
javascript
// 验证API密钥
async function validateApiKey() {
try {
await client.listIndices();
return true;
} catch (error) {
if (error.status === 401 || error.status === 403) {
return false;
}
throw error;
}
}
请求超时 #
javascript
// 设置超时
const client = algoliasearch('APP_ID', 'API_KEY', {
requestOptions: {
timeout: 5000 // 5秒超时
}
});
总结 #
错误处理要点:
| 要点 | 说明 |
|---|---|
| 状态码 | 按状态码分类处理 |
| 重试 | 指数退避重试机制 |
| 降级 | 缓存、默认数据 |
| 提示 | 用户友好的错误信息 |
| 调试 | 日志、getRankingInfo |
| 监控 | 错误追踪、统计 |
恭喜你完成了Algolia文档的学习!
最后更新:2026-03-28