Skip to content

Commit

Permalink
Display better 404 messages when generated dartdoc page is missing. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
isoos committed Sep 11, 2024
1 parent 25c0f6f commit 2e80d2f
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
12 changes: 9 additions & 3 deletions app/lib/dartdoc/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:json_annotation/json_annotation.dart';
part 'models.g.dart';

/// Describes the resolved version and the URL redirect info.
@JsonSerializable()
@JsonSerializable(includeIfNull: false)
class ResolvedDocUrlVersion {
/// The version to use to display the documentation.
final String version;
Expand All @@ -20,13 +20,18 @@ class ResolvedDocUrlVersion {
/// * `""` (indicating empty response)
final String urlSegment;

/// When the resolution is empty, the 404 response will have this message.
final String? message;

ResolvedDocUrlVersion({
required this.version,
required this.urlSegment,
this.message,
});

ResolvedDocUrlVersion.empty()
: version = '',
ResolvedDocUrlVersion.empty({
required this.message,
}) : version = '',
urlSegment = '';

factory ResolvedDocUrlVersion.fromJson(Map<String, dynamic> json) =>
Expand All @@ -35,4 +40,5 @@ class ResolvedDocUrlVersion {
Map<String, dynamic> toJson() => _$ResolvedDocUrlVersionToJson(this);

bool get isEmpty => version.isEmpty || urlSegment.isEmpty;
bool get isLatestStable => urlSegment == 'latest';
}
21 changes: 16 additions & 5 deletions app/lib/dartdoc/models.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions app/lib/frontend/handlers/documentation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ Future<shelf.Response> documentationHandler(shelf.Request request) async {
final version = docFilePath.version!;
final resolved = await _resolveDocUrlVersion(package, version);
if (resolved.isEmpty) {
return notFoundHandler(request);
return notFoundHandler(
request,
body: resolved.message ?? default404NotFound,
);
}
if (version != resolved.urlSegment) {
return redirectResponse(pkgDocUrl(
Expand Down Expand Up @@ -147,7 +150,8 @@ Future<ResolvedDocUrlVersion> _resolveDocUrlVersion(
if (version == 'latest') {
final latestFinished = await taskBackend.latestFinishedVersion(package);
if (latestFinished == null) {
return ResolvedDocUrlVersion.empty();
return ResolvedDocUrlVersion.empty(
message: 'Analysis has not started yet.');
}
final latestVersion = await packageBackend.getLatestVersion(package);
return ResolvedDocUrlVersion(
Expand All @@ -159,7 +163,7 @@ Future<ResolvedDocUrlVersion> _resolveDocUrlVersion(
// Do not resolve if package version does not exists.
final pv = await packageBackend.lookupPackageVersion(package, version);
if (pv == null) {
return ResolvedDocUrlVersion.empty();
return ResolvedDocUrlVersion.empty(message: 'Not found.');
}

// Select the closest version (may be the same as version) that has a finished analysis.
Expand Down
27 changes: 26 additions & 1 deletion app/lib/task/handlers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:pub_dev/shared/handlers.dart';
import 'package:pub_dev/shared/redis_cache.dart';
import 'package:pub_dev/shared/urls.dart';
import 'package:pub_dev/task/backend.dart';
import 'package:pub_dev/task/models.dart';
import 'package:shelf/shelf.dart' as shelf;

const _safeMimeTypes = {
Expand Down Expand Up @@ -111,7 +112,31 @@ Future<shelf.Response> handleDartDoc(
});
// We use empty string to indicate missing file or bug in the file
if (htmlBytes == null || htmlBytes.isEmpty) {
return notFoundHandler(request);
final status = await taskBackend.packageStatus(package);
final vs = status.versions[version];
if (vs == null) {
return notFoundHandler(
request,
body: resolvedDocUrlVersion.isLatestStable
? 'Analysis has not started yet.'
: 'Version not selected for analysis.',
);
}
String? message;
switch (vs.status) {
case PackageVersionStatus.pending:
case PackageVersionStatus.running:
message = 'Analysis has not finished yet.';
break;
case PackageVersionStatus.failed:
message =
'Analysis has failed, no `dartdoc` output has been generated.';
break;
case PackageVersionStatus.completed:
message = '`dartdoc` did not generate this page.';
break;
}
return notFoundHandler(request, body: message);
}
return htmlBytesResponse(htmlBytes);
}
Expand Down

0 comments on commit 2e80d2f

Please sign in to comment.