mirror of
https://github.com/samsonjs/media.git
synced 2026-04-07 11:35:46 +00:00
Simplify network-related error codes
This change removes ERROR_CODE_IO_NETWORK_UNAVAILABLE, ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED, and ERROR_CODE_IO_DNS_FAILED in favor of keeping only ERROR_CODE_IO_NETWORK_CONNECTION_FAILED. PiperOrigin-RevId: 388715972
This commit is contained in:
parent
f23ab8e2c1
commit
17723c0836
4 changed files with 50 additions and 92 deletions
|
|
@ -669,12 +669,11 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
if (message != null && Ascii.toLowerCase(message).contains("err_cleartext_not_permitted")) {
|
||||
throw new CleartextNotPermittedException(connectionOpenException, dataSpec);
|
||||
}
|
||||
@PlaybackException.ErrorCode
|
||||
int errorCode =
|
||||
getErrorCodeForException(
|
||||
connectionOpenException, /* occurredWhileOpeningConnection*/ true);
|
||||
throw new OpenException(
|
||||
connectionOpenException, dataSpec, errorCode, getStatus(urlRequest));
|
||||
connectionOpenException,
|
||||
dataSpec,
|
||||
PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
|
||||
getStatus(urlRequest));
|
||||
} else if (!connectionOpened) {
|
||||
// The timeout was reached before the connection was opened.
|
||||
throw new OpenException(
|
||||
|
|
@ -685,10 +684,13 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
// An interruption means the operation is being cancelled, in which case this exception should
|
||||
// not cause the player to fail. If it does, it likely means that the owner of the operation
|
||||
// is failing to swallow the interruption, which makes us enter an invalid state.
|
||||
throw new OpenException(
|
||||
new InterruptedIOException(),
|
||||
dataSpec,
|
||||
PlaybackException.ERROR_CODE_IO_UNSPECIFIED,
|
||||
PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK,
|
||||
Status.INVALID);
|
||||
}
|
||||
|
||||
|
|
@ -1029,7 +1031,9 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
throw new OpenException(
|
||||
e,
|
||||
dataSpec,
|
||||
getErrorCodeForException(e, /* occurredWhileOpeningConnection= */ false),
|
||||
e instanceof SocketTimeoutException
|
||||
? PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT
|
||||
: PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
|
||||
Status.READING_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
|
@ -1099,11 +1103,8 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
if (exception instanceof HttpDataSourceException) {
|
||||
throw (HttpDataSourceException) exception;
|
||||
} else {
|
||||
throw new HttpDataSourceException(
|
||||
exception,
|
||||
dataSpec,
|
||||
getErrorCodeForException(exception, /* occurredWhileOpeningConnection= */ false),
|
||||
HttpDataSourceException.TYPE_READ);
|
||||
throw HttpDataSourceException.createForIOException(
|
||||
exception, dataSpec, HttpDataSourceException.TYPE_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1116,27 +1117,6 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
return readBuffer;
|
||||
}
|
||||
|
||||
@PlaybackException.ErrorCode
|
||||
private static int getErrorCodeForException(
|
||||
IOException exception, boolean occurredWhileOpeningConnection) {
|
||||
if (exception instanceof UnknownHostException) {
|
||||
return PlaybackException.ERROR_CODE_IO_DNS_FAILED;
|
||||
}
|
||||
@Nullable String message = exception.getMessage();
|
||||
if (message != null) {
|
||||
if (message.contains("net::ERR_INTERNET_DISCONNECTED")) {
|
||||
return PlaybackException.ERROR_CODE_IO_NETWORK_UNAVAILABLE;
|
||||
} else if (message.contains("net::ERR_CONTENT_LENGTH_MISMATCH")
|
||||
|| message.contains("net::ERR_SOCKET_NOT_CONNECTED")) {
|
||||
return PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED;
|
||||
}
|
||||
}
|
||||
if (occurredWhileOpeningConnection) {
|
||||
return PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED;
|
||||
}
|
||||
return PlaybackException.ERROR_CODE_IO_UNSPECIFIED;
|
||||
}
|
||||
|
||||
private static boolean isCompressed(UrlResponseInfo info) {
|
||||
for (Map.Entry<String, String> entry : info.getAllHeadersAsList()) {
|
||||
if (entry.getKey().equalsIgnoreCase("Content-Encoding")) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
|
|
@ -48,13 +49,10 @@ public class PlaybackException extends Exception implements Bundleable {
|
|||
ERROR_CODE_TIMEOUT,
|
||||
ERROR_CODE_FAILED_RUNTIME_CHECK,
|
||||
ERROR_CODE_IO_UNSPECIFIED,
|
||||
ERROR_CODE_IO_NETWORK_UNAVAILABLE,
|
||||
ERROR_CODE_IO_NETWORK_CONNECTION_FAILED,
|
||||
ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT,
|
||||
ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED,
|
||||
ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE,
|
||||
ERROR_CODE_IO_BAD_HTTP_STATUS,
|
||||
ERROR_CODE_IO_DNS_FAILED,
|
||||
ERROR_CODE_IO_FILE_NOT_FOUND,
|
||||
ERROR_CODE_IO_NO_PERMISSION,
|
||||
ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED,
|
||||
|
|
@ -107,32 +105,38 @@ public class PlaybackException extends Exception implements Bundleable {
|
|||
|
||||
/** Caused by an Input/Output error which could not be identified. */
|
||||
public static final int ERROR_CODE_IO_UNSPECIFIED = 2000;
|
||||
/** Caused by the lack of network connectivity while trying to access a network resource. */
|
||||
public static final int ERROR_CODE_IO_NETWORK_UNAVAILABLE = 2001;
|
||||
/** Caused by a failure while establishing a network connection. */
|
||||
public static final int ERROR_CODE_IO_NETWORK_CONNECTION_FAILED = 2002;
|
||||
/**
|
||||
* Caused by a network connection failure.
|
||||
*
|
||||
* <p>The following is a non-exhaustive list of possible reasons:
|
||||
*
|
||||
* <ul>
|
||||
* <li>There is no network connectivity (you can check this by querying {@link
|
||||
* ConnectivityManager#getActiveNetwork}).
|
||||
* <li>The URL's domain is misspelled or does not exist.
|
||||
* <li>The target host is unreachable.
|
||||
* <li>The server unexpectedly closes the connection.
|
||||
* </ul>
|
||||
*/
|
||||
public static final int ERROR_CODE_IO_NETWORK_CONNECTION_FAILED = 2001;
|
||||
/** Caused by a network timeout, meaning the server is taking too long to fulfill a request. */
|
||||
public static final int ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT = 2003;
|
||||
/** Caused by an existing connection being unexpectedly closed. */
|
||||
public static final int ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED = 2004;
|
||||
public static final int ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT = 2002;
|
||||
/**
|
||||
* Caused by a server returning a resource with an invalid "Content-Type" HTTP header value.
|
||||
*
|
||||
* <p>For example, this can happen when the player is expecting a piece of media, but the server
|
||||
* returns a paywall HTML page, with content type "text/html".
|
||||
*/
|
||||
public static final int ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE = 2005;
|
||||
public static final int ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE = 2003;
|
||||
/** Caused by an HTTP server returning an unexpected HTTP response status code. */
|
||||
public static final int ERROR_CODE_IO_BAD_HTTP_STATUS = 2006;
|
||||
/** Caused by the player failing to resolve a hostname. */
|
||||
public static final int ERROR_CODE_IO_DNS_FAILED = 2007;
|
||||
public static final int ERROR_CODE_IO_BAD_HTTP_STATUS = 2004;
|
||||
/** Caused by a non-existent file. */
|
||||
public static final int ERROR_CODE_IO_FILE_NOT_FOUND = 2008;
|
||||
public static final int ERROR_CODE_IO_FILE_NOT_FOUND = 2005;
|
||||
/**
|
||||
* Caused by lack of permission to perform an IO operation. For example, lack of permission to
|
||||
* access internet or external storage.
|
||||
*/
|
||||
public static final int ERROR_CODE_IO_NO_PERMISSION = 2009;
|
||||
public static final int ERROR_CODE_IO_NO_PERMISSION = 2006;
|
||||
/**
|
||||
* Caused by the player trying to access cleartext HTTP traffic (meaning http:// rather than
|
||||
* https://) when the app's Network Security Configuration does not permit it.
|
||||
|
|
@ -140,9 +144,9 @@ public class PlaybackException extends Exception implements Bundleable {
|
|||
* <p>See <a href="https://exoplayer.dev/issues/cleartext-not-permitted">this corresponding
|
||||
* troubleshooting topic</a>.
|
||||
*/
|
||||
public static final int ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED = 2010;
|
||||
public static final int ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED = 2007;
|
||||
/** Caused by reading data out of the data bound. */
|
||||
public static final int ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE = 2011;
|
||||
public static final int ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE = 2008;
|
||||
|
||||
// Content parsing errors (3xxx).
|
||||
|
||||
|
|
@ -234,20 +238,14 @@ public class PlaybackException extends Exception implements Bundleable {
|
|||
return "ERROR_CODE_FAILED_RUNTIME_CHECK";
|
||||
case ERROR_CODE_IO_UNSPECIFIED:
|
||||
return "ERROR_CODE_IO_UNSPECIFIED";
|
||||
case ERROR_CODE_IO_NETWORK_UNAVAILABLE:
|
||||
return "ERROR_CODE_IO_NETWORK_UNAVAILABLE";
|
||||
case ERROR_CODE_IO_NETWORK_CONNECTION_FAILED:
|
||||
return "ERROR_CODE_IO_NETWORK_CONNECTION_FAILED";
|
||||
case ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT:
|
||||
return "ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT";
|
||||
case ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED:
|
||||
return "ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED";
|
||||
case ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE:
|
||||
return "ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE";
|
||||
case ERROR_CODE_IO_BAD_HTTP_STATUS:
|
||||
return "ERROR_CODE_IO_BAD_HTTP_STATUS";
|
||||
case ERROR_CODE_IO_DNS_FAILED:
|
||||
return "ERROR_CODE_IO_DNS_FAILED";
|
||||
case ERROR_CODE_IO_FILE_NOT_FOUND:
|
||||
return "ERROR_CODE_IO_FILE_NOT_FOUND";
|
||||
case ERROR_CODE_IO_NO_PERMISSION:
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ import com.google.android.exoplayer2.util.Util;
|
|||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Predicate;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -215,24 +215,20 @@ public interface HttpDataSource extends DataSource {
|
|||
*/
|
||||
public static HttpDataSourceException createForIOException(
|
||||
IOException cause, DataSpec dataSpec, @Type int type) {
|
||||
@PlaybackException.ErrorCode int errorCode = PlaybackException.ERROR_CODE_IO_UNSPECIFIED;
|
||||
@PlaybackException.ErrorCode int errorCode;
|
||||
@Nullable String message = cause.getMessage();
|
||||
if (cause instanceof SocketTimeoutException) {
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT;
|
||||
} else if (cause instanceof UnknownHostException) {
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_DNS_FAILED;
|
||||
} else if (cause instanceof InterruptedIOException) {
|
||||
// An interruption means the operation is being cancelled, in which case this exception
|
||||
// should not cause the player to fail. If it does, it likely means that the owner of the
|
||||
// operation is failing to swallow the interruption, which makes us enter an invalid state.
|
||||
errorCode = PlaybackException.ERROR_CODE_FAILED_RUNTIME_CHECK;
|
||||
} else if (message != null
|
||||
&& Ascii.toLowerCase(message).matches("cleartext.*not permitted.*")) {
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED;
|
||||
} else {
|
||||
@Nullable String message = cause.getMessage();
|
||||
if (message != null) {
|
||||
if (Ascii.toLowerCase(message).matches("cleartext.*not permitted.*")) {
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED;
|
||||
} else if (message.contains("unexpected end of stream")) {
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == TYPE_OPEN && errorCode == PlaybackException.ERROR_CODE_IO_UNSPECIFIED) {
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED;
|
||||
}
|
||||
errorCode = PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED;
|
||||
}
|
||||
return errorCode == PlaybackException.ERROR_CODE_IO_CLEARTEXT_NOT_PERMITTED
|
||||
? new CleartextNotPermittedException(cause, dataSpec)
|
||||
|
|
|
|||
|
|
@ -22,16 +22,12 @@ import androidx.annotation.Nullable;
|
|||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.PlaybackException;
|
||||
import java.io.IOException;
|
||||
import java.net.BindException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.PortUnreachableException;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/** A UDP {@link DataSource}. */
|
||||
public final class UdpDataSource extends BaseDataSource {
|
||||
|
|
@ -115,25 +111,14 @@ public final class UdpDataSource extends BaseDataSource {
|
|||
} else {
|
||||
socket = new DatagramSocket(socketAddress);
|
||||
}
|
||||
socket.setSoTimeout(socketTimeoutMillis);
|
||||
} catch (SecurityException e) {
|
||||
throw new UdpDataSourceException(e, PlaybackException.ERROR_CODE_IO_NO_PERMISSION);
|
||||
} catch (UnknownHostException e) {
|
||||
// TODO (internal b/184262323): Handle the case where UnknownHostException is thrown due to
|
||||
// lack of network access.
|
||||
throw new UdpDataSourceException(e, PlaybackException.ERROR_CODE_IO_DNS_FAILED);
|
||||
} catch (BindException e) {
|
||||
throw new UdpDataSourceException(e, PlaybackException.ERROR_CODE_IO_NETWORK_UNAVAILABLE);
|
||||
} catch (IOException e) {
|
||||
throw new UdpDataSourceException(
|
||||
e, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED);
|
||||
}
|
||||
|
||||
try {
|
||||
socket.setSoTimeout(socketTimeoutMillis);
|
||||
} catch (SocketException e) {
|
||||
throw new UdpDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
|
||||
}
|
||||
|
||||
opened = true;
|
||||
transferStarted(dataSpec);
|
||||
return C.LENGTH_UNSET;
|
||||
|
|
@ -149,13 +134,12 @@ public final class UdpDataSource extends BaseDataSource {
|
|||
// We've read all of the data from the current packet. Get another.
|
||||
try {
|
||||
socket.receive(packet);
|
||||
} catch (PortUnreachableException e) {
|
||||
throw new UdpDataSourceException(e, PlaybackException.ERROR_CODE_IO_NETWORK_UNAVAILABLE);
|
||||
} catch (SocketTimeoutException e) {
|
||||
throw new UdpDataSourceException(
|
||||
e, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT);
|
||||
} catch (IOException e) {
|
||||
throw new UdpDataSourceException(e, PlaybackException.ERROR_CODE_IO_UNSPECIFIED);
|
||||
throw new UdpDataSourceException(
|
||||
e, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED);
|
||||
}
|
||||
packetRemaining = packet.getLength();
|
||||
bytesTransferred(packetRemaining);
|
||||
|
|
|
|||
Loading…
Reference in a new issue