Skip to content

Commit 8e97da6

Browse files
Merge branch 'main' into kw-hybrid-profiling
2 parents b154784 + f461caa commit 8e97da6

10 files changed

Lines changed: 154 additions & 61 deletions

File tree

CHANGELOG.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,40 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
- (Internal) Extract Android Profiler and Measurements for Hybrid SDKs ([#3016](https://github.com/getsentry/sentry-java/pull/3016))
8+
- (Internal) Remove SentryOptions dependency from AndroidProfiler ([#3051](https://github.com/getsentry/sentry-java/pull/3051))
9+
- (Internal) Add `readBytesFromFile` for use in Hybrid SDKs ([#3052](https://github.com/getsentry/sentry-java/pull/3052))
10+
511
### Fixes
612

13+
- Fix SIGSEV, SIGABRT and SIGBUS crashes happening after/around the August Google Play System update, see [#2955](https://github.com/getsentry/sentry-java/issues/2955) for more details (fix provided by Native SDK bump)
714
- Ensure DSN uses http/https protocol ([#3044](https://github.com/getsentry/sentry-java/pull/3044))
815

16+
### Dependencies
17+
18+
- Bump Native SDK from v0.6.6 to v0.6.7 ([#3048](https://github.com/getsentry/sentry-java/pull/3048))
19+
- [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#067)
20+
- [diff](https://github.com/getsentry/sentry-native/compare/0.6.6...0.6.7)
21+
22+
## 6.33.2-beta.1
23+
24+
### Fixes
25+
26+
- Fix SIGSEV, SIGABRT and SIGBUS crashes happening after/around the August Google Play System update, see [#2955](https://github.com/getsentry/sentry-java/issues/2955) for more details (fix provided by Native SDK bump)
27+
28+
### Dependencies
29+
30+
- Bump Native SDK from v0.6.6 to v0.6.7 ([#3048](https://github.com/getsentry/sentry-java/pull/3048))
31+
- [changelog](https://github.com/getsentry/sentry-native/blob/master/CHANGELOG.md#067)
32+
- [diff](https://github.com/getsentry/sentry-native/compare/0.6.6...0.6.7)
33+
934
### Features
1035

1136
- Add current activity name to app context ([#2999](https://github.com/getsentry/sentry-java/pull/2999))
12-
- (Internal) Extract Android Profiler and Measurements for Hybrid SDKs ([#3016](https://github.com/getsentry/sentry-java/pull/3016))
13-
- (Internal) Remove SentryOptions dependency from AndroidProfiler ([#3051](https://github.com/getsentry/sentry-java/pull/3051))
37+
- Add `MonitorConfig` param to `CheckInUtils.withCheckIn` ([#3038](https://github.com/getsentry/sentry-java/pull/3038))
38+
- This makes it easier to automatically create or update (upsert) monitors.
1439

1540
## 6.33.1
1641

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ android.useAndroidX=true
1010
android.defaults.buildfeatures.buildconfig=true
1111

1212
# Release information
13-
versionName=6.33.1
13+
versionName=6.33.2-beta.1
1414

1515
# Override the SDK name on native crashes on Android
1616
sentryAndroidSdkName=sentry.native.android

sentry/api/sentry.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4334,6 +4334,7 @@ public abstract class io/sentry/transport/TransportResult {
43344334
public final class io/sentry/util/CheckInUtils {
43354335
public fun <init> ()V
43364336
public static fun isIgnored (Ljava/util/List;Ljava/lang/String;)Z
4337+
public static fun withCheckIn (Ljava/lang/String;Lio/sentry/MonitorConfig;Ljava/util/concurrent/Callable;)Ljava/lang/Object;
43374338
public static fun withCheckIn (Ljava/lang/String;Ljava/util/concurrent/Callable;)Ljava/lang/Object;
43384339
}
43394340

@@ -4374,6 +4375,7 @@ public final class io/sentry/util/ExceptionUtils {
43744375
public final class io/sentry/util/FileUtils {
43754376
public fun <init> ()V
43764377
public static fun deleteRecursively (Ljava/io/File;)Z
4378+
public static fun readBytesFromFile (Ljava/lang/String;J)[B
43774379
public static fun readText (Ljava/io/File;)Ljava/lang/String;
43784380
}
43794381

sentry/src/main/java/io/sentry/SentryEnvelopeItem.java

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry;
22

3+
import static io.sentry.util.FileUtils.readBytesFromFile;
34
import static io.sentry.vendor.Base64.NO_PADDING;
45
import static io.sentry.vendor.Base64.NO_WRAP;
56

@@ -9,13 +10,11 @@
910
import io.sentry.util.JsonSerializationUtils;
1011
import io.sentry.util.Objects;
1112
import io.sentry.vendor.Base64;
12-
import java.io.BufferedInputStream;
1313
import java.io.BufferedReader;
1414
import java.io.BufferedWriter;
1515
import java.io.ByteArrayInputStream;
1616
import java.io.ByteArrayOutputStream;
1717
import java.io.File;
18-
import java.io.FileInputStream;
1918
import java.io.IOException;
2019
import java.io.InputStreamReader;
2120
import java.io.OutputStreamWriter;
@@ -304,48 +303,6 @@ private static void ensureAttachmentSizeLimit(
304303
return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes());
305304
}
306305

307-
private static byte[] readBytesFromFile(String pathname, long maxFileLength)
308-
throws SentryEnvelopeException {
309-
try {
310-
File file = new File(pathname);
311-
312-
if (!file.isFile()) {
313-
throw new SentryEnvelopeException(
314-
String.format(
315-
"Reading the item %s failed, because the file located at the path is not a file.",
316-
pathname));
317-
}
318-
319-
if (!file.canRead()) {
320-
throw new SentryEnvelopeException(
321-
String.format("Reading the item %s failed, because can't read the file.", pathname));
322-
}
323-
324-
if (file.length() > maxFileLength) {
325-
throw new SentryEnvelopeException(
326-
String.format(
327-
"Dropping item, because its size located at '%s' with %d bytes is bigger "
328-
+ "than the maximum allowed size of %d bytes.",
329-
pathname, file.length(), maxFileLength));
330-
}
331-
332-
try (FileInputStream fileInputStream = new FileInputStream(pathname);
333-
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
334-
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
335-
byte[] bytes = new byte[1024];
336-
int length;
337-
int offset = 0;
338-
while ((length = inputStream.read(bytes)) != -1) {
339-
outputStream.write(bytes, offset, length);
340-
}
341-
return outputStream.toByteArray();
342-
}
343-
} catch (IOException | SecurityException exception) {
344-
throw new SentryEnvelopeException(
345-
String.format("Reading the item %s failed.\n%s", pathname, exception.getMessage()));
346-
}
347-
}
348-
349306
public static @NotNull SentryEnvelopeItem fromClientReport(
350307
final @NotNull ISerializer serializer, final @NotNull ClientReport clientReport)
351308
throws IOException {

sentry/src/main/java/io/sentry/util/CheckInUtils.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.sentry.CheckInStatus;
55
import io.sentry.DateUtils;
66
import io.sentry.IHub;
7+
import io.sentry.MonitorConfig;
78
import io.sentry.Sentry;
89
import io.sentry.protocol.SentryId;
910
import java.util.List;
@@ -18,21 +19,29 @@ public final class CheckInUtils {
1819
/**
1920
* Helper method to send monitor check-ins for a {@link Callable}
2021
*
22+
* @param monitorSlug - the slug of the monitor
23+
* @param monitorConfig - configuration of the monitor, can be used for upserting schedule
2124
* @param callable - the {@link Callable} to be called
2225
* @return the return value of the {@link Callable}
2326
* @param <U> - the result type of the {@link Callable}
2427
*/
2528
public static <U> U withCheckIn(
26-
final @NotNull String monitorSlug, final @NotNull Callable<U> callable) throws Exception {
29+
final @NotNull String monitorSlug,
30+
final @Nullable MonitorConfig monitorConfig,
31+
final @NotNull Callable<U> callable)
32+
throws Exception {
2733
final @NotNull IHub hub = Sentry.getCurrentHub();
2834
final long startTime = System.currentTimeMillis();
2935
boolean didError = false;
3036

3137
hub.pushScope();
3238
TracingUtils.startNewTrace(hub);
3339

34-
@Nullable
35-
SentryId checkInId = hub.captureCheckIn(new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS));
40+
CheckIn inProgressCheckIn = new CheckIn(monitorSlug, CheckInStatus.IN_PROGRESS);
41+
if (monitorConfig != null) {
42+
inProgressCheckIn.setMonitorConfig(monitorConfig);
43+
}
44+
@Nullable SentryId checkInId = hub.captureCheckIn(inProgressCheckIn);
3645
try {
3746
return callable.call();
3847
} catch (Throwable t) {
@@ -47,6 +56,19 @@ public static <U> U withCheckIn(
4756
}
4857
}
4958

59+
/**
60+
* Helper method to send monitor check-ins for a {@link Callable}
61+
*
62+
* @param monitorSlug - the slug of the monitor
63+
* @param callable - the {@link Callable} to be called
64+
* @return the return value of the {@link Callable}
65+
* @param <U> - the result type of the {@link Callable}
66+
*/
67+
public static <U> U withCheckIn(
68+
final @NotNull String monitorSlug, final @NotNull Callable<U> callable) throws Exception {
69+
return withCheckIn(monitorSlug, null, callable);
70+
}
71+
5072
/** Checks if a check-in for a monitor (CRON) has been ignored. */
5173
@ApiStatus.Internal
5274
public static boolean isIgnored(

sentry/src/main/java/io/sentry/util/FileUtils.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package io.sentry.util;
22

3+
import java.io.BufferedInputStream;
34
import java.io.BufferedReader;
5+
import java.io.ByteArrayOutputStream;
46
import java.io.File;
7+
import java.io.FileInputStream;
58
import java.io.FileReader;
69
import java.io.IOException;
710
import org.jetbrains.annotations.ApiStatus;
@@ -60,4 +63,52 @@ public static boolean deleteRecursively(@Nullable File file) {
6063
}
6164
return contentBuilder.toString();
6265
}
66+
67+
/**
68+
* Reads the content of a path into a byte array. If the path is does not exists, it's not a file,
69+
* can't be read or is larger than max size allowed IOException is thrown. Do not use with large
70+
* files, as the byte array is kept in memory!
71+
*
72+
* @param pathname file to read
73+
* @return a byte array containing all the content of the file
74+
* @throws IOException In case of error reading the file
75+
*/
76+
public static byte[] readBytesFromFile(String pathname, long maxFileLength)
77+
throws IOException, SecurityException {
78+
File file = new File(pathname);
79+
80+
if (!file.exists()) {
81+
throw new IOException(String.format("File '%s' doesn't exists", file.getName()));
82+
}
83+
84+
if (!file.isFile()) {
85+
throw new IOException(
86+
String.format("Reading path %s failed, because it's not a file.", pathname));
87+
}
88+
89+
if (!file.canRead()) {
90+
throw new IOException(
91+
String.format("Reading the item %s failed, because can't read the file.", pathname));
92+
}
93+
94+
if (file.length() > maxFileLength) {
95+
throw new IOException(
96+
String.format(
97+
"Reading file failed, because size located at '%s' with %d bytes is bigger "
98+
+ "than the maximum allowed size of %d bytes.",
99+
pathname, file.length(), maxFileLength));
100+
}
101+
102+
try (FileInputStream fileInputStream = new FileInputStream(pathname);
103+
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
104+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
105+
byte[] bytes = new byte[1024];
106+
int length;
107+
int offset = 0;
108+
while ((length = inputStream.read(bytes)) != -1) {
109+
outputStream.write(bytes, offset, length);
110+
}
111+
return outputStream.toByteArray();
112+
}
113+
}
63114
}

sentry/src/test/java/io/sentry/JsonSerializerTest.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.sentry
22

3-
import io.sentry.exception.SentryEnvelopeException
43
import io.sentry.profilemeasurements.ProfileMeasurement
54
import io.sentry.profilemeasurements.ProfileMeasurementValue
65
import io.sentry.protocol.Device
@@ -1037,7 +1036,7 @@ class JsonSerializerTest {
10371036
.log(
10381037
eq(SentryLevel.ERROR),
10391038
eq("Failed to create envelope item. Dropping it."),
1040-
any<SentryEnvelopeException>()
1039+
any<IOException>()
10411040
)
10421041
}
10431042

sentry/src/test/java/io/sentry/SentryEnvelopeItemTest.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.mockito.kotlin.whenever
1313
import java.io.BufferedWriter
1414
import java.io.ByteArrayOutputStream
1515
import java.io.File
16+
import java.io.IOException
1617
import java.io.OutputStreamWriter
1718
import java.nio.charset.Charset
1819
import kotlin.test.AfterTest
@@ -120,7 +121,7 @@ class SentryEnvelopeItemTest {
120121

121122
val item = SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize)
122123

123-
assertFailsWith<SentryEnvelopeException>(
124+
assertFailsWith<IOException>(
124125
"Reading the attachment ${attachment.pathname} failed, because the file located at " +
125126
"the path is not a file."
126127
) {
@@ -140,7 +141,7 @@ class SentryEnvelopeItemTest {
140141

141142
val item = SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize)
142143

143-
assertFailsWith<SentryEnvelopeException>(
144+
assertFailsWith<IOException>(
144145
"Reading the attachment ${attachment.pathname} failed, " +
145146
"because can't read the file."
146147
) {
@@ -163,7 +164,7 @@ class SentryEnvelopeItemTest {
163164

164165
val item = SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize)
165166

166-
assertFailsWith<SentryEnvelopeException>("Reading the attachment ${attachment.pathname} failed.") {
167+
assertFailsWith<SecurityException>("Reading the attachment ${attachment.pathname} failed.") {
167168
item.data
168169
}
169170

@@ -244,12 +245,12 @@ class SentryEnvelopeItemTest {
244245
file.writeBytes(fixture.bytesTooBig)
245246
val attachment = Attachment(file.path)
246247

247-
val exception = assertFailsWith<SentryEnvelopeException> {
248+
val exception = assertFailsWith<IOException> {
248249
SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize).data
249250
}
250251

251252
assertEquals(
252-
"Dropping item, because its size located at " +
253+
"Reading file failed, because size located at " +
253254
"'${fixture.pathname}' with ${file.length()} bytes is bigger than the maximum " +
254255
"allowed size of ${fixture.maxAttachmentSize} bytes.",
255256
exception.message
@@ -317,7 +318,7 @@ class SentryEnvelopeItemTest {
317318
}
318319
file.writeBytes(fixture.bytes)
319320
file.setReadable(false)
320-
assertFailsWith<SentryEnvelopeException>("Dropping profiling trace data, because the file ${file.path} doesn't exists") {
321+
assertFailsWith<IOException>("Dropping profiling trace data, because the file ${file.path} doesn't exists") {
321322
SentryEnvelopeItem.fromProfilingTrace(profilingTraceData, fixture.maxAttachmentSize, mock()).data
322323
}
323324
}
@@ -344,12 +345,12 @@ class SentryEnvelopeItemTest {
344345
whenever(it.traceFile).thenReturn(file)
345346
}
346347

347-
val exception = assertFailsWith<SentryEnvelopeException> {
348+
val exception = assertFailsWith<IOException> {
348349
SentryEnvelopeItem.fromProfilingTrace(profilingTraceData, fixture.maxAttachmentSize, mock()).data
349350
}
350351

351352
assertEquals(
352-
"Dropping item, because its size located at " +
353+
"Reading file failed, because size located at " +
353354
"'${fixture.pathname}' with ${file.length()} bytes is bigger than the maximum " +
354355
"allowed size of ${fixture.maxAttachmentSize} bytes.",
355356
exception.message

0 commit comments

Comments
 (0)