1 | /* |
2 | Copyright (C) 2002-2004 MySQL AB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of version 2 of the GNU General Public License as |
6 | published by the Free Software Foundation. |
7 | |
8 | There are special exceptions to the terms and conditions of the GPL |
9 | as it is applied to this software. View the full text of the |
10 | exception in file EXCEPTIONS-CONNECTOR-J in the directory of this |
11 | software distribution. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | |
22 | |
23 | |
24 | */ |
25 | package com.mysql.jdbc; |
26 | |
27 | import java.net.BindException; |
28 | |
29 | import java.sql.SQLException; |
30 | |
31 | /** |
32 | * An exception to represent communications errors with the database. |
33 | * |
34 | * Attempts to provide 'friendler' error messages to end-users, including last |
35 | * time a packet was sent to the database, what the client-timeout is set to, |
36 | * and whether the idle time has been exceeded. |
37 | * |
38 | * @author Mark Matthews |
39 | * |
40 | * @version $Id: CommunicationsException.java,v 1.1.2.1 2005/05/13 18:58:37 |
41 | * mmatthews Exp $ |
42 | */ |
43 | public class CommunicationsException extends SQLException { |
44 | |
45 | private static final long DEFAULT_WAIT_TIMEOUT_SECONDS = 28800; |
46 | |
47 | private static final int DUE_TO_TIMEOUT_FALSE = 0; |
48 | |
49 | private static final int DUE_TO_TIMEOUT_MAYBE = 2; |
50 | |
51 | private static final int DUE_TO_TIMEOUT_TRUE = 1; |
52 | |
53 | private String exceptionMessage; |
54 | |
55 | public CommunicationsException(Connection conn, long lastPacketSentTimeMs, |
56 | Exception underlyingException) { |
57 | |
58 | long serverTimeoutSeconds = 0; |
59 | boolean isInteractiveClient = false; |
60 | |
61 | if (conn != null) { |
62 | isInteractiveClient = conn.getInteractiveClient(); |
63 | |
64 | String serverTimeoutSecondsStr = null; |
65 | |
66 | if (isInteractiveClient) { |
67 | serverTimeoutSecondsStr = conn |
68 | .getServerVariable("interactive_timeout"); //$NON-NLS-1$ |
69 | } else { |
70 | serverTimeoutSecondsStr = conn |
71 | .getServerVariable("wait_timeout"); //$NON-NLS-1$ |
72 | } |
73 | |
74 | if (serverTimeoutSecondsStr != null) { |
75 | try { |
76 | serverTimeoutSeconds = Long |
77 | .parseLong(serverTimeoutSecondsStr); |
78 | } catch (NumberFormatException nfe) { |
79 | serverTimeoutSeconds = 0; |
80 | } |
81 | } |
82 | } |
83 | |
84 | StringBuffer exceptionMessageBuf = new StringBuffer(); |
85 | |
86 | if (lastPacketSentTimeMs == 0) { |
87 | lastPacketSentTimeMs = System.currentTimeMillis(); |
88 | } |
89 | |
90 | long timeSinceLastPacket = (System.currentTimeMillis() - lastPacketSentTimeMs) / 1000; |
91 | |
92 | int dueToTimeout = DUE_TO_TIMEOUT_FALSE; |
93 | |
94 | StringBuffer timeoutMessageBuf = null; |
95 | |
96 | if (serverTimeoutSeconds != 0) { |
97 | if (timeSinceLastPacket > serverTimeoutSeconds) { |
98 | dueToTimeout = DUE_TO_TIMEOUT_TRUE; |
99 | |
100 | timeoutMessageBuf = new StringBuffer(); |
101 | |
102 | timeoutMessageBuf.append(Messages |
103 | .getString("CommunicationsException.2")); //$NON-NLS-1$ |
104 | |
105 | if (!isInteractiveClient) { |
106 | timeoutMessageBuf.append(Messages |
107 | .getString("CommunicationsException.3")); //$NON-NLS-1$ |
108 | } else { |
109 | timeoutMessageBuf.append(Messages |
110 | .getString("CommunicationsException.4")); //$NON-NLS-1$ |
111 | } |
112 | |
113 | } |
114 | } else if (timeSinceLastPacket > DEFAULT_WAIT_TIMEOUT_SECONDS) { |
115 | dueToTimeout = DUE_TO_TIMEOUT_MAYBE; |
116 | |
117 | timeoutMessageBuf = new StringBuffer(); |
118 | |
119 | timeoutMessageBuf.append(Messages |
120 | .getString("CommunicationsException.5")); //$NON-NLS-1$ |
121 | timeoutMessageBuf.append(Messages |
122 | .getString("CommunicationsException.6")); //$NON-NLS-1$ |
123 | timeoutMessageBuf.append(Messages |
124 | .getString("CommunicationsException.7")); //$NON-NLS-1$ |
125 | timeoutMessageBuf.append(Messages |
126 | .getString("CommunicationsException.8")); //$NON-NLS-1$ |
127 | } |
128 | |
129 | if (dueToTimeout == DUE_TO_TIMEOUT_TRUE |
130 | || dueToTimeout == DUE_TO_TIMEOUT_MAYBE) { |
131 | |
132 | exceptionMessageBuf.append(Messages |
133 | .getString("CommunicationsException.9")); //$NON-NLS-1$ |
134 | exceptionMessageBuf.append(timeSinceLastPacket); |
135 | exceptionMessageBuf.append(Messages |
136 | .getString("CommunicationsException.10")); //$NON-NLS-1$ |
137 | |
138 | if (timeoutMessageBuf != null) { |
139 | exceptionMessageBuf.append(timeoutMessageBuf); |
140 | } |
141 | |
142 | exceptionMessageBuf.append(Messages |
143 | .getString("CommunicationsException.11")); //$NON-NLS-1$ |
144 | exceptionMessageBuf.append(Messages |
145 | .getString("CommunicationsException.12")); //$NON-NLS-1$ |
146 | exceptionMessageBuf.append(Messages |
147 | .getString("CommunicationsException.13")); //$NON-NLS-1$ |
148 | |
149 | } else { |
150 | // |
151 | // Attempt to determine the reason for the underlying exception |
152 | // (we can only make a best-guess here) |
153 | // |
154 | |
155 | if (underlyingException instanceof BindException) { |
156 | // too many client connections??? |
157 | exceptionMessageBuf.append(Messages |
158 | .getString("CommunicationsException.14")); //$NON-NLS-1$ |
159 | exceptionMessageBuf.append(Messages |
160 | .getString("CommunicationsException.15")); //$NON-NLS-1$ |
161 | exceptionMessageBuf.append(Messages |
162 | .getString("CommunicationsException.16")); //$NON-NLS-1$ |
163 | exceptionMessageBuf.append(Messages |
164 | .getString("CommunicationsException.17")); //$NON-NLS-1$ |
165 | exceptionMessageBuf.append(Messages |
166 | .getString("CommunicationsException.18")); //$NON-NLS-1$ |
167 | exceptionMessageBuf.append(Messages |
168 | .getString("CommunicationsException.19")); //$NON-NLS-1$ |
169 | } |
170 | } |
171 | |
172 | if (exceptionMessageBuf.length() == 0) { |
173 | // We haven't figured out a good reason, so copy it. |
174 | exceptionMessageBuf.append(Messages |
175 | .getString("CommunicationsException.20")); //$NON-NLS-1$ |
176 | |
177 | if (underlyingException != null) { |
178 | exceptionMessageBuf.append(Messages |
179 | .getString("CommunicationsException.21")); //$NON-NLS-1$ |
180 | exceptionMessageBuf.append(Util |
181 | .stackTraceToString(underlyingException)); |
182 | } |
183 | |
184 | if (conn != null && conn.getMaintainTimeStats() && |
185 | !conn.getParanoid()) { |
186 | exceptionMessageBuf.append("\n\nLast packet sent to the server was "); |
187 | exceptionMessageBuf.append(System.currentTimeMillis() - lastPacketSentTimeMs); |
188 | exceptionMessageBuf.append(" ms ago."); |
189 | } |
190 | } |
191 | |
192 | this.exceptionMessage = exceptionMessageBuf.toString(); |
193 | } |
194 | |
195 | /* |
196 | * (non-Javadoc) |
197 | * |
198 | * @see java.lang.Throwable#getMessage() |
199 | */ |
200 | public String getMessage() { |
201 | return this.exceptionMessage; |
202 | } |
203 | |
204 | /* |
205 | * (non-Javadoc) |
206 | * |
207 | * @see java.sql.SQLException#getSQLState() |
208 | */ |
209 | public String getSQLState() { |
210 | return SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE; |
211 | } |
212 | |
213 | } |