001/* 002 * Copyright (c) 2026 Singular 003 * SPDX-License-Identifier: MIT 004 */ 005 006package ai.singlr.openai; 007 008/** Exception thrown when OpenAI API operations fail. */ 009public class OpenAIException extends RuntimeException { 010 011 private final int statusCode; 012 013 public OpenAIException(String message) { 014 super(message); 015 this.statusCode = 0; 016 } 017 018 public OpenAIException(String message, Throwable cause) { 019 super(message, cause); 020 this.statusCode = 0; 021 } 022 023 public OpenAIException(String message, int statusCode) { 024 super(message); 025 this.statusCode = statusCode; 026 } 027 028 public OpenAIException(String message, int statusCode, Throwable cause) { 029 super(message, cause); 030 this.statusCode = statusCode; 031 } 032 033 public int statusCode() { 034 return statusCode; 035 } 036 037 public boolean isClientError() { 038 return statusCode >= 400 && statusCode < 500; 039 } 040 041 public boolean isServerError() { 042 return statusCode >= 500; 043 } 044 045 /** 046 * Whether this error is retryable. Network errors (status 0), request timeouts (408), rate limits 047 * (429), and server errors (5xx) are considered retryable. 048 */ 049 public boolean isRetryable() { 050 return statusCode == 0 || statusCode == 408 || statusCode == 429 || statusCode >= 500; 051 } 052}