Github user attilapiros commented on a diff in the pull request: https://github.com/apache/spark/pull/20474#discussion_r165739588 --- Diff: core/src/main/scala/org/apache/spark/status/api/v1/OneApplicationResource.scala --- @@ -51,6 +52,43 @@ private[v1] class AbstractApplicationResource extends BaseAppResource { @Path("executors") def executorList(): Seq[ExecutorSummary] = withUI(_.store.executorList(true)) + @GET + @Path("executors/{executorId}/threads") + def threadDump(@PathParam("executorId") executorId: String): Response = withUI { ui => + uiRoot.executorThreadDumpsNotAvailableError().getOrElse { + val safeExecutorId = + Option(UIUtils.stripXSS(executorId)).map { executorId => + UIUtils.decodeURLParameter(executorId) + }.getOrElse { + throw new IllegalArgumentException(s"Missing executorId parameter") + } + + def isAllDigits(x: String) = x.forall(Character.isDigit) + + if (executorId != SparkContext.DRIVER_IDENTIFIER && !isAllDigits(executorId)) { + Response.serverError() + .entity(s"Invalid executorId: neither '${SparkContext.DRIVER_IDENTIFIER}' nor number.") + .status(Response.Status.BAD_REQUEST) + .build() + } else { + if (ui.store.asOption(ui.store.executorSummary(executorId)).exists(!_.isActive)) { --- End diff -- This is exactly the current behaviour as for false it goes into: ```scala } else { ui.sc.flatMap(_.getExecutorThreadDump(safeExecutorId)) .map(Response.ok(_).build()) .getOrElse( Response.serverError() .entity("No stack traces are available.") .status(Response.Status.NOT_FOUND) .build()) } ``` Then further to: ```scala .getOrElse( Response.serverError() .entity("No stack traces are available.") .status(Response.Status.NOT_FOUND) .build()) ``` See the test screenshot for "Not existing (well formatted) executor ID". Or did I misunderstood your requirement?
--- --------------------------------------------------------------------- To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For additional commands, e-mail: reviews-h...@spark.apache.org