From db26ac676bb500c4ccf2132d29b392834dfaceb0 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:44:40 +0900 Subject: [PATCH] =?UTF-8?q?Misskey=E3=81=AE=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=81=AB=E5=9E=8B=E3=82=92=E3=81=A4=E3=81=91=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/misskey_dart.dart | 1 + lib/src/data/misskey_exception.dart | 20 ++ lib/src/data/misskey_exception.freezed.dart | 245 ++++++++++++++++++++ lib/src/data/misskey_exception.g.dart | 32 +++ lib/src/services/api_service.dart | 60 ++++- test/misskey_note_test.dart | 5 + 6 files changed, 355 insertions(+), 8 deletions(-) create mode 100644 lib/src/data/misskey_exception.dart create mode 100644 lib/src/data/misskey_exception.freezed.dart create mode 100644 lib/src/data/misskey_exception.g.dart diff --git a/lib/misskey_dart.dart b/lib/misskey_dart.dart index a286fa42..f8fcd0d8 100644 --- a/lib/misskey_dart.dart +++ b/lib/misskey_dart.dart @@ -128,6 +128,7 @@ export 'src/data/i/registry/i_registry_keys_with_type_request.dart'; export 'src/data/i/registry/i_registry_remove_request.dart'; export 'src/data/i/registry/i_registry_scopes_with_domain_response.dart'; export 'src/data/i/registry/i_registry_set_request.dart'; +export 'src/data/misskey_exception.dart'; export 'src/data/notes/notes_clips_request.dart'; export 'src/data/notes/notes_timeline_request.dart'; export 'src/data/notes/notes_create_request.dart'; diff --git a/lib/src/data/misskey_exception.dart b/lib/src/data/misskey_exception.dart new file mode 100644 index 00000000..8ff52f44 --- /dev/null +++ b/lib/src/data/misskey_exception.dart @@ -0,0 +1,20 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'misskey_exception.freezed.dart'; +part 'misskey_exception.g.dart'; + +@freezed +class MisskeyException with _$MisskeyException implements Exception { + const factory MisskeyException({ + required String id, + required String code, + required String message, + required MisskeyExceptionKind kind, + Map? info, + }) = _MisskeyException; + + factory MisskeyException.fromJson(Map json) => + _$MisskeyExceptionFromJson(json); +} + +enum MisskeyExceptionKind { client, server } diff --git a/lib/src/data/misskey_exception.freezed.dart b/lib/src/data/misskey_exception.freezed.dart new file mode 100644 index 00000000..065c8060 --- /dev/null +++ b/lib/src/data/misskey_exception.freezed.dart @@ -0,0 +1,245 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'misskey_exception.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +MisskeyException _$MisskeyExceptionFromJson(Map json) { + return _MisskeyException.fromJson(json); +} + +/// @nodoc +mixin _$MisskeyException { + String get id => throw _privateConstructorUsedError; + String get code => throw _privateConstructorUsedError; + String get message => throw _privateConstructorUsedError; + MisskeyExceptionKind get kind => throw _privateConstructorUsedError; + Map? get info => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $MisskeyExceptionCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $MisskeyExceptionCopyWith<$Res> { + factory $MisskeyExceptionCopyWith( + MisskeyException value, $Res Function(MisskeyException) then) = + _$MisskeyExceptionCopyWithImpl<$Res, MisskeyException>; + @useResult + $Res call( + {String id, + String code, + String message, + MisskeyExceptionKind kind, + Map? info}); +} + +/// @nodoc +class _$MisskeyExceptionCopyWithImpl<$Res, $Val extends MisskeyException> + implements $MisskeyExceptionCopyWith<$Res> { + _$MisskeyExceptionCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? code = null, + Object? message = null, + Object? kind = null, + Object? info = freezed, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + code: null == code + ? _value.code + : code // ignore: cast_nullable_to_non_nullable + as String, + message: null == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String, + kind: null == kind + ? _value.kind + : kind // ignore: cast_nullable_to_non_nullable + as MisskeyExceptionKind, + info: freezed == info + ? _value.info + : info // ignore: cast_nullable_to_non_nullable + as Map?, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$MisskeyExceptionImplCopyWith<$Res> + implements $MisskeyExceptionCopyWith<$Res> { + factory _$$MisskeyExceptionImplCopyWith(_$MisskeyExceptionImpl value, + $Res Function(_$MisskeyExceptionImpl) then) = + __$$MisskeyExceptionImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String id, + String code, + String message, + MisskeyExceptionKind kind, + Map? info}); +} + +/// @nodoc +class __$$MisskeyExceptionImplCopyWithImpl<$Res> + extends _$MisskeyExceptionCopyWithImpl<$Res, _$MisskeyExceptionImpl> + implements _$$MisskeyExceptionImplCopyWith<$Res> { + __$$MisskeyExceptionImplCopyWithImpl(_$MisskeyExceptionImpl _value, + $Res Function(_$MisskeyExceptionImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? code = null, + Object? message = null, + Object? kind = null, + Object? info = freezed, + }) { + return _then(_$MisskeyExceptionImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + code: null == code + ? _value.code + : code // ignore: cast_nullable_to_non_nullable + as String, + message: null == message + ? _value.message + : message // ignore: cast_nullable_to_non_nullable + as String, + kind: null == kind + ? _value.kind + : kind // ignore: cast_nullable_to_non_nullable + as MisskeyExceptionKind, + info: freezed == info + ? _value._info + : info // ignore: cast_nullable_to_non_nullable + as Map?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$MisskeyExceptionImpl implements _MisskeyException { + const _$MisskeyExceptionImpl( + {required this.id, + required this.code, + required this.message, + required this.kind, + final Map? info}) + : _info = info; + + factory _$MisskeyExceptionImpl.fromJson(Map json) => + _$$MisskeyExceptionImplFromJson(json); + + @override + final String id; + @override + final String code; + @override + final String message; + @override + final MisskeyExceptionKind kind; + final Map? _info; + @override + Map? get info { + final value = _info; + if (value == null) return null; + if (_info is EqualUnmodifiableMapView) return _info; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); + } + + @override + String toString() { + return 'MisskeyException(id: $id, code: $code, message: $message, kind: $kind, info: $info)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$MisskeyExceptionImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.code, code) || other.code == code) && + (identical(other.message, message) || other.message == message) && + (identical(other.kind, kind) || other.kind == kind) && + const DeepCollectionEquality().equals(other._info, _info)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, id, code, message, kind, + const DeepCollectionEquality().hash(_info)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$MisskeyExceptionImplCopyWith<_$MisskeyExceptionImpl> get copyWith => + __$$MisskeyExceptionImplCopyWithImpl<_$MisskeyExceptionImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$MisskeyExceptionImplToJson( + this, + ); + } +} + +abstract class _MisskeyException implements MisskeyException { + const factory _MisskeyException( + {required final String id, + required final String code, + required final String message, + required final MisskeyExceptionKind kind, + final Map? info}) = _$MisskeyExceptionImpl; + + factory _MisskeyException.fromJson(Map json) = + _$MisskeyExceptionImpl.fromJson; + + @override + String get id; + @override + String get code; + @override + String get message; + @override + MisskeyExceptionKind get kind; + @override + Map? get info; + @override + @JsonKey(ignore: true) + _$$MisskeyExceptionImplCopyWith<_$MisskeyExceptionImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/src/data/misskey_exception.g.dart b/lib/src/data/misskey_exception.g.dart new file mode 100644 index 00000000..11308521 --- /dev/null +++ b/lib/src/data/misskey_exception.g.dart @@ -0,0 +1,32 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'misskey_exception.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$MisskeyExceptionImpl _$$MisskeyExceptionImplFromJson( + Map json) => + _$MisskeyExceptionImpl( + id: json['id'] as String, + code: json['code'] as String, + message: json['message'] as String, + kind: $enumDecode(_$MisskeyExceptionKindEnumMap, json['kind']), + info: json['info'] as Map?, + ); + +Map _$$MisskeyExceptionImplToJson( + _$MisskeyExceptionImpl instance) => + { + 'id': instance.id, + 'code': instance.code, + 'message': instance.message, + 'kind': _$MisskeyExceptionKindEnumMap[instance.kind]!, + 'info': instance.info, + }; + +const _$MisskeyExceptionKindEnumMap = { + MisskeyExceptionKind.client: 'client', + MisskeyExceptionKind.server: 'server', +}; diff --git a/lib/src/services/api_service.dart b/lib/src/services/api_service.dart index 6bd48357..1a10ff01 100644 --- a/lib/src/services/api_service.dart +++ b/lib/src/services/api_service.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:dio/dio.dart'; +import 'package:misskey_dart/misskey_dart.dart'; class ApiService { final Dio dio = Dio(); @@ -34,8 +35,21 @@ class ApiService { value == null && (excludeRemoveNullPredicate == null || !excludeRemoveNullPredicate.call(key, value))); - final response = await dio.request(path, data: request); - return response.data; + try { + final response = await dio.request(path, data: request); + return response.data; + } on DioException catch (e) { + Exception exception; + try { + exception = MisskeyException.fromJson( + (e.response?.data as Map)["error"] + as Map, + ); + } catch (_) { + exception = e; + } + throw exception; + } } Future postWithFile( @@ -51,13 +65,28 @@ class ApiService { )) ]) ..removeWhere((key, value) => value == null); - final response = await dio.request(path, + try { + final response = await dio.request( + path, data: FormData.fromMap(request), options: Options( contentType: "multipart/form-data", method: "POST", - )); - return response.data; + ), + ); + return response.data; + } on DioException catch (e) { + Exception exception; + try { + exception = MisskeyException.fromJson( + (e.response?.data as Map)["error"] + as Map, + ); + } catch (_) { + exception = e; + } + throw exception; + } } Future postWithBinary( @@ -73,12 +102,27 @@ class ApiService { "file", MultipartFile.fromBytes(binaryData, filename: fileName)) ]) ..removeWhere((key, value) => value == null); - final response = await dio.request(path, + try { + final response = await dio.request( + path, data: FormData.fromMap(request), options: Options( contentType: "multipart/form-data", method: "POST", - )); - return response.data; + ), + ); + return response.data; + } on DioException catch (e) { + Exception exception; + try { + exception = MisskeyException.fromJson( + (e.response?.data as Map)["error"] + as Map, + ); + } catch (_) { + exception = e; + } + throw exception; + } } } diff --git a/test/misskey_note_test.dart b/test/misskey_note_test.dart index 68a9550a..9fdd5e23 100644 --- a/test/misskey_note_test.dart +++ b/test/misskey_note_test.dart @@ -49,6 +49,11 @@ void main() async { ); }); }); + + test("exception", () async { + final future = userClient.notes.create(NotesCreateRequest()); + await expectLater(future, throwsA(isA())); + }); }); test(